<?xml version="1.0" encoding="UTF-8"?><rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:atom="http://www.w3.org/2005/Atom" version="2.0" xmlns:cc="http://cyber.law.harvard.edu/rss/creativeCommonsRssModule.html">
    <channel>
        <title><![CDATA[Stories by Alyssa X on Medium]]></title>
        <description><![CDATA[Stories by Alyssa X on Medium]]></description>
        <link>https://medium.com/@alyssax?source=rss-957f2a5d71e4------2</link>
        <image>
            <url>https://cdn-images-1.medium.com/fit/c/150/150/1*k40c6J7KMecUCuNNuuJIrA.png</url>
            <title>Stories by Alyssa X on Medium</title>
            <link>https://medium.com/@alyssax?source=rss-957f2a5d71e4------2</link>
        </image>
        <generator>Medium</generator>
        <lastBuildDate>Sat, 14 Nov 2026 01:16:05 GMT</lastBuildDate>
        <atom:link href="https://medium.com/@alyssax/feed" rel="self" type="application/rss+xml"/>
        <webMaster><![CDATA[yourfriends@medium.com]]></webMaster>
        <atom:link href="http://medium.superfeedr.com/" rel="hub"/>
        <item>
            <title><![CDATA[How I built a MacOS app and made $5000+ in a week]]></title>
            <link>https://medium.com/women-make/how-i-built-a-macos-app-and-made-5000-in-a-week-de25c7be0458?source=rss-957f2a5d71e4------2</link>
            <guid isPermaLink="false">https://medium.com/p/de25c7be0458</guid>
            <category><![CDATA[productivity]]></category>
            <category><![CDATA[startup]]></category>
            <category><![CDATA[programming]]></category>
            <category><![CDATA[money]]></category>
            <category><![CDATA[design]]></category>
            <dc:creator><![CDATA[Alyssa X]]></dc:creator>
            <pubDate>Wed, 23 Mar 2022 15:36:51 GMT</pubDate>
            <atom:updated>2022-12-26T01:06:27.404Z</atom:updated>
            <content:encoded><![CDATA[<figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*rpKZsgYCsC8JCLLvZTm6Tw.png" /></figure><p>Back in late January I was in Barcelona, and I was feeling exhausted. I had been traveling back and forth for the past 6 months or so, and there was no end in sight. While I had gotten accustomed to the whole ordeal, taking mere minutes to pack everything up and leave for the airport, there was one thing that was driving me insane. <strong>My MacBook.</strong></p><p>So, on my day to day I use a lot of different apps for my workflow, some of which are relatively lightweight (email, calendar), but others a lot more power-hungry (Figma, After Effects, Chrome…). I leave them open so I can be more productive, switching between them effortlessly, but the problem is that they use up a lot of battery. When I travel, since I often don’t have access to a power source, I run out of battery really quickly. And while I could shut down the laptop, I often still need to get things done on the way, so it’s not ideal. So I need to close all the apps, and reopen them one by one when I get to my destination. Ugh.</p><p><a href="https://alyssax.substack.com/embed">Alyssa X</a></p><h3>The product idea</h3><iframe src="https://cdn.embedly.com/widgets/media.html?src=https%3A%2F%2Fcards.producthunt.com%2Fcards%2Fposts%2F332569%3Fv%3D1&amp;display_name=Product+Hunt&amp;url=https%3A%2F%2Fwww.producthunt.com%2Fposts%2Flater-aa762753-cafe-475e-9acb-d534de9e6adf&amp;image=https%3A%2F%2Fph-files.imgix.net%2Fc76a27f9-01b7-4c01-ba10-4123090d44ca.gif%3Fauto%3Dformat%26fit%3Dmax%26h%3D405%26w%3D500&amp;key=a19fcc184b9711e1b4764040d3dc5c07&amp;type=text%2Fhtml&amp;schema=producthunt" width="500" height="405" frameborder="0" scrolling="no"><a href="https://medium.com/media/80afe537377b8cf76c9ff27859d321ed/href">https://medium.com/media/80afe537377b8cf76c9ff27859d321ed/href</a></iframe><p>Being a serial maker (<a href="https://newsletter.alyssax.com/">I’ve built and shipped 12+ products over the past few years</a>), I thought that maybe I could solve this problem with an app. I wasn’t sure at first if it would be possible, since I had only worked on web projects before, but I thought I could still give it a shot. Besides, I also thought the app could be used for other purposes beyond traveling, for example to clean up the workspace before a screen sharing/screen recording, or to take a break from work, so other people might also find it useful.</p><p>The concept I came up with was a tool where you pressed a button to save all of your active apps (closing them), and then you would press it again to restore them. Super simple, but still incredibly useful for me. I called it <a href="https://getlater.app/">Later</a>.</p><h3>A quick prototype</h3><p>With the idea defined, I thought the next logical step would be trying to build some sort of proof of concept. I felt it would be easiest if the app was in the menu bar (also since I had seen <a href="https://www.producthunt.com/posts/progress-bar-osx">some success</a> with those on Product Hunt), but <strong>I didn’t know how to build it</strong>.</p><p>I looked around, and it seemed that using Swift in Xcode was the best option, especially since I’d have to use a lot of native APIs. I had no idea how to use it, so I started looking things up, and thankfully I found this tutorial by <a href="https://www.hackingwithswift.com/">HackingWithSwift</a> which helped me set up the base for the app:</p><iframe src="https://cdn.embedly.com/widgets/media.html?src=https%3A%2F%2Fwww.youtube.com%2Fembed%2Fii89L7LVAs4%3Ffeature%3Doembed&amp;display_name=YouTube&amp;url=https%3A%2F%2Fwww.youtube.com%2Fwatch%3Fv%3Dii89L7LVAs4&amp;image=https%3A%2F%2Fi.ytimg.com%2Fvi%2Fii89L7LVAs4%2Fhqdefault.jpg&amp;key=a19fcc184b9711e1b4764040d3dc5c07&amp;type=text%2Fhtml&amp;schema=youtube" width="854" height="480" frameborder="0" scrolling="no"><a href="https://medium.com/media/00ff2cf9b430c1d7d569bd1b95321c26/href">https://medium.com/media/00ff2cf9b430c1d7d569bd1b95321c26/href</a></iframe><p>From there I basically kept searching for the things I needed all over StackOverflow, the Apple Forums, and the Swift docs.</p><p>The main gist of it was getting all the NSRunningApplication instances, filtering based on the activationPolicy to only get the visible apps (those with a presence in the dock, I didn’t want to close any background process or menu bar app), and then saving the data through UserDefaults. Then to open them I simply had to run a Process with the executableURL property of the applications and any specific settings. There were some roadblocks on the way, for example I realized in order to use the terminate() method I needed to <a href="https://stackoverflow.com/questions/7018354/remove-sandboxing">remove sandboxing</a> from the app, which prevented it from being able to go into the App Store, but I just thought I could figure it out later, and I just kept on building.</p><p>After a couple of days I got it working, with a super simple setup that programmatically closed and opened the windows. I had essentially solved the problem by this point, but I wanted to go further and package it up with a nice UI, and possibly other functions.</p><h3>Creating the product</h3><p>I wanted to build this as soon as possible, so I just jumped on Figma, and I quickly designed the UI (inspired by the <a href="https://topnotch.app/">TopNotch app</a>) for all the different possible states. In order to make it as user-friendly as possible, I included a screenshot of the moment when the user saves their apps, as well as some metadata and information about them, and a way to override sessions or get rid of them entirely.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/0*QvWpDJgNnCGupy3Z" /><figcaption>I also included a light mode in the designs, but I didn’t end up using it</figcaption></figure><p>I also added several additional settings (although I changed some of them on launch, and added more on request), such as starting on logging, ignoring system apps, a timer function, and more.</p><p>Then I just had to implement it. I used Storyboard on Xcode which was a bit of a nightmare. In retrospect it might have been a better idea to use SwiftUI and code the whole interface, but I assumed it might be easier for me to use a visual tool since I’m a designer.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/0*yAWy04GIjqpwT04A" /><figcaption>How the Storyboard file looked at one point</figcaption></figure><p>It was a horrible experience, taking forever to get everything to align correctly, using constraints to keep the elements positioned with respect to each other, and trying to find where everything was with a ton of tabs and “hidden” actions (for example, holding the Control key while dragging an element creates a reference to it in code) but eventually I got it working, and the app was ready to launch.</p><p>I wanted to get some feedback before launching though, so I made a tweet and I asked if anyone wanted to test out the app:</p><h3>Alyssa X on Twitter: &quot;I decided to learn Swift the past week &amp; built a MacOS app ✨The app closes all your windows and reopens them later (can also be set to a timer ⏲️). It helps save 🔋 while traveling, switch off from work, prepare for meetings/screen sharing...DM me if you want to try it! 📩 pic.twitter.com/rKB7HuA9if / Twitter&quot;</h3><p>I decided to learn Swift the past week &amp; built a MacOS app ✨The app closes all your windows and reopens them later (can also be set to a timer ⏲️). It helps save 🔋 while traveling, switch off from work, prepare for meetings/screen sharing...DM me if you want to try it!</p><p>To my surprise the tweet really took off, and I ended up with hundreds of DMs. I spoke to a few people who gave me all sorts of ideas, and after making a few changes, I decided I should start preparing for the launch.</p><h3>Building a memorable landing page</h3><p>I first had to create a landing page, to try to sell the product. I really liked the one for the <a href="https://muzzleapp.com/">Muzzle app</a>, so I tried doing something similar that worked for my product.</p><p>I thought it would be fun to replicate the specific problem my app was solving in the landing page. Basically, have the user be overwhelmed with a lot of windows when they open the page, and show that my app can solve the issue.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/0*PMJGhzK9ypEo4-YD" /><figcaption>The landing page for the app. Yes, it’s supposed to look like this.</figcaption></figure><p><a href="https://getlater.app/">As you can see</a>, a bit of a risky move since some of the windows overlap the copy, but it ended up paying off. I also added a countdown with a limited time offer for the app, since I wanted to experiment with some techniques to increase sales, and I wanted people to be aware that the app had just launched.</p><h3>Making an eye-catching teaser</h3><p>Then I wanted to make a video, so I could share it on social media and on Product Hunt, as a way to showcase what the app does. I did some brainstorming, and I figured the best way would for it to be a little story. Here’s what I came up with:</p><ol><li>Show somebody on their MacBook with a lot of apps open, just passing the time with Wordle (trying to be relatable…).</li><li>Suddenly, they receive a notification for a meeting they forgot about, and messages from a coworker and their boss asking them to share their screen.</li><li>Have a slight moment of panic (they’re not prepared at all, they have all sorts of things open they might want to get back to later, etc.).</li><li>Show that the solution is using my app, Later, saving all the windows with one click, and restoring them for later.</li></ol><p>I made a very quick storyboard (yes, it’s ugly), and I was ready to get started.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/0*-pEQ8gsH1JaHCvOp" /><figcaption>A very rough storyboard</figcaption></figure><p>First I needed to get all the assets for the video. So I used Figma and I broke apart my app popup mockups, and exported each part that needed to be animated separately. I also created a background with a wallpaper and the menu bar, and I decided to skip on the dock because of added complexity (trust me, it would have taken forever). I also reused the windows I had created for the landing page previously to use in the teaser (which also helped with consistency).</p><p>Then I moved on to After Effects to create the video to put in the screen of the mockup. I created a composition for each of the different scenes:</p><ul><li><strong>First scene:</strong> The cluster of windows and the notifications</li><li><strong>Second scene:</strong> Saving all the windows with the app</li><li><strong>Final scene:</strong> Restoring the apps</li></ul><p>It took me a while, but eventually I got all the animations the way I wanted, so I rendered all the scenes and exported the videos.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/0*jk09n2iiqCu-65eu" /><figcaption>Animating the laptop model in Rotato</figcaption></figure><p>Next, I opened <a href="https://rotato.app/">Rotato</a>, and skimmed through some of the articles to learn how to use the tool. I created a new project, used a Macbook M1 model, and set up each scene.</p><p>Finally, I came back to After Effects and put it all together, with the text transitions in between. I got inspired by the <a href="https://www.youtube.com/watch?v=jk6sz25OZgw">Don’t Blink</a> commercial that Apple made a few years ago, and I used a similar style of typography for my teaser.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/0*7GPDljjvFl4JFmQR" /><figcaption>How my After Effects project looked like after finishing the teaser</figcaption></figure><p>I also looked through the Youtube audio library to find some music to go with the teaser (usually I don’t put any, but when there’s text it doesn’t feel right to make a silent video). I found this really fun song called <a href="https://www.youtube.com/watch?v=laWFEnNM4sE">Two Little Bums</a> by The Great North Sound Society, and I thought it was perfect for it.</p><p>And that was it, the video was ready! Here’s how it turned out:</p><iframe src="https://cdn.embedly.com/widgets/media.html?src=https%3A%2F%2Fwww.youtube.com%2Fembed%2FMd37eKBRXhk%3Ffeature%3Doembed&amp;display_name=YouTube&amp;url=https%3A%2F%2Fwww.youtube.com%2Fwatch%3Fv%3DMd37eKBRXhk&amp;image=https%3A%2F%2Fi.ytimg.com%2Fvi%2FMd37eKBRXhk%2Fhqdefault.jpg&amp;key=a19fcc184b9711e1b4764040d3dc5c07&amp;type=text%2Fhtml&amp;schema=youtube" width="854" height="480" frameborder="0" scrolling="no"><a href="https://medium.com/media/730edfb23fa651161ac4a86e0aea5116/href">https://medium.com/media/730edfb23fa651161ac4a86e0aea5116/href</a></iframe><h3>Last things to do before launch</h3><p>Since the app was unsandboxed, it couldn’t go in the App Store. So I had to self-distribute it somehow.</p><p>I wanted to charge for the product, so I looked into the <a href="https://developer.paddle.com/reference/ZG9jOjI1MzU0MDYx-mac-sdk-setup">Paddle Mac SDK</a>, which was really easy to set up. I just had to import it into the Xcode project, create a product in the dashboard, and connect it. It automatically generates license codes which can then be activated on download. Finally I just added a script into my landing page to embed the payment flow, and it was ready to go.</p><p>Another thing I had to look at were software updates. I wanted to avoid a logistical nightmare having to push patches and all sorts of new features in the future, so I integrated <a href="https://sparkle-project.org/">Sparkle</a> with the app. The way it works is through a XML file that contains all the information about the latest version, as well as a link to download it from. Then the version is either automatically installed for all the users (if they have the setting on), or it can be manually installed by pressing on “Check for updates” in the settings.</p><p>Finally, I exported the app, and I used <a href="https://github.com/sindresorhus/create-dmg">this tool</a> to create a fancy DMG to install the app, easy enough!</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*H8p2N1qH9RWba8GAHni4sw.png" /><figcaption>The DMG for the app, to drag the app into the Applications folder to install it</figcaption></figure><p>But then I realized the app wouldn’t run unless I signed it, so I had to get an Apple Developer Account. This was easier said than done though, and it actually ended up being a huge ordeal which pushed the launch by several weeks.</p><h3>The soft launch</h3><p>I was planning on doing a big launch simultaneously on Twitter and Product Hunt, but I was a bit stressed about it, so I decided to do a bit of a “soft launch”, and share it early somewhere else to get some feedback beforehand.</p><p>I remembered about Pieter Levels then having <a href="https://levels.io/hoodmaps/">written about his experiences</a> promoting his products, and how he found Reddit to be a really successful medium as it was able to target customers much better than Product Hunt/Hacker News could. I was a bit hesitant and intimidated by it, but I decided to make an account, I looked for a fitting subreddit, and thankfully I found <a href="https://www.reddit.com/r/macapps/">r/MacApps</a> which worked perfectly for my product. To my surprise I looked in the rules and they were fine with self-promotion, which is quite unusual for Reddit as a whole, so I thought I would give it a shot.</p><iframe src="https://cdn.embedly.com/widgets/media.html?src=https%3A%2F%2Fwww.youtube.com%2Fembed%2FFN144KdOIGM%3Ffeature%3Doembed&amp;display_name=YouTube&amp;url=https%3A%2F%2Fwww.youtube.com%2Fwatch%3Fv%3DFN144KdOIGM&amp;image=https%3A%2F%2Fi.ytimg.com%2Fvi%2FFN144KdOIGM%2Fhqdefault.jpg&amp;key=a19fcc184b9711e1b4764040d3dc5c07&amp;type=text%2Fhtml&amp;schema=youtube" width="854" height="480" frameborder="0" scrolling="no"><a href="https://medium.com/media/ab28d3ec29182581eac9dfc011b3d371/href">https://medium.com/media/ab28d3ec29182581eac9dfc011b3d371/href</a></iframe><p>It was a bit of a rollercoaster.</p><p>I started getting comments with all sorts of questions, things I hadn’t gotten from any of my testers, and my morale took a big hit. First they told me that my app needed to have a trial period to test it out. Then they said that it was dangerous for the app to close apps by default, that it would be better if it hid them instead. I also was told that $15 was way too expensive for the app, and that I should lower it to $5. I was feeling overwhelmed and I quickly started pushing updates and making all sorts of changes, I tried setting up a trial using the <a href="https://developer.paddle.com/reference/ZG9jOjI1MzU0MDYx-mac-sdk-setup">Paddle SDK</a> which I wasn’t successful with, so I just gave out a bunch of free coupons which were quickly used up. I then switched the default behavior to hide instead of terminate apps and added a checkbox to revert to the original functionality. I also got super stressed and lowered the price to $5 due to peer pressure.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/984/0*AFvZGPNV3KUTVubm" /><figcaption>My post became the #7 most most upvoted post of all time</figcaption></figure><p>Despite all the criticism, after making all the changes I started getting lots of positive comments, and it quickly became the <a href="https://www.reddit.com/r/macapps/comments/sxuxqx/i_made_a_menu_bar_app_that_saves_all_your_windows/">#1 hot post on the subreddit</a>. I got ~40 sales from the post, and people told me I should raise the price since Mac apps are a niche market and I was providing lifetime updates together with the price, so it ended up going for $12. In the end my post became the 7th most upvoted of all time in r/MacApps, which was amazing.</p><h3>The actual launch</h3><p>I’ve learnt a lot from my previous launches, so I had everything scheduled in advance. I didn’t want to stress over it and stay up all night but sadly it still happened due to being super anxious, and I was like a zombie for the whole day, just randomly falling asleep every so on.</p><p>My post went out automatically on Product Hunt at 12:00 AM PT, and I just kept on refreshing non-stop, hoping people would see it, but nothing was happening. I messaged a few people if they could check it out, but everyone was asleep. The other posts by companies were all racking up upvotes, and mine was way on the bottom, it wasn’t even visible in the front page so I couldn’t make it grow organically. I panicked, I wasn’t sure whether to make a tweet early (I always tweet at 8AM SF time since it’s best for my audience), but I felt it could ruin everything, so I held off. I ended up sending out an email on <a href="https://alyssax.substack.com/">my newsletter</a> alerting my subscribers about my launch, and thankfully it got me enough upvotes to stay in the top 10.</p><p>8AM PT came around, so my tweet went out:</p><h3>Alyssa X on Twitter: &quot;Save all your apps for later with just one click 🖱️Later is a Mac menu bar app that clears and restores your workspace 💻 Switch off from work, tidy up your desktop before a meeting, save battery, schedule apps for later, and more.👉 https://t.co/mV8ma90EtB pic.twitter.com/LnVkaCNxyS / Twitter&quot;</h3><p>Save all your apps for later with just one click 🖱️Later is a Mac menu bar app that clears and restores your workspace 💻 Switch off from work, tidy up your desktop before a meeting, save battery, schedule apps for later, and more.👉 https://t.co/mV8ma90EtB pic.twitter.com/LnVkaCNxyS</p><p>I got incredibly lucky, and a few big accounts retweeted it early on, which made the tweet go viral pretty easily. My notifications were going wild, and I was getting lots of sales.</p><p>An hour later I realized the Apple news site iMore had <a href="https://www.imore.com/clear-your-macs-desktop-apps-and-reopen-them-when-needed-later">decided to cover my app</a>, which was really prominent in their home page, so I was getting even more sales from them. Even <a href="https://www.fastcompany.com/90728620/mac-clear-open-windows">Fast Company</a> picked it up!</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*zVdjJsMh2-a5X2BBRF9F_Q.png" /></figure><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*buKHD0kq8KJx74owYWDwrg.png" /><figcaption>The articles talking about Later on Fast Company and iMore, respectively</figcaption></figure><h3>The results</h3><p>In the end it all went much better than I had expected. Although my product didn’t make it to the top 5 on Product Hunt, within a week I made over $5000 in net revenue from hundreds of copies sold. As of March 21st, it’s over $6600.</p><p>Most of my sales seemed to come from the US which I was expecting considering my audience and the fact that it was for MacOS only (Apple dominates the market in the US). In terms of website sources, most trackable sales came from Twitter, followed by Product Hunt, iMore, and finally Reddit. That said a large number don’t have a source, so it’s really hard to tell exactly, for Reddit for instance I could tell it probably underestimated them as I have 40+ transactions before I posted on Product Hunt, and it wasn’t shared anywhere else.</p><p>In retrospect, I feel like it might have been a better idea to have an annual subscription, considering the app includes all future updates. Something like $5/year could have been reasonable, but I tried looking into ways to set it up, even contacting Paddle, and they didn’t seem to have a good system in place with their licensing system, so I just gave up in the end.</p><p>Anyway, that’s the story. I hope you enjoyed reading!</p><p>I’m Alyssa X, a serial entrepreneur who has shipped 12+ products (with over 100K users), been nominated twice as Maker of The Year, and created some of the <a href="https://www.producthunt.com/@alyssaxuu/made">top products on Product Hunt</a>.</p><p>Follow me on <a href="https://twitter.com/alyssaxuu">Twitter</a> and subscribe to <a href="https://alyssax.substack.com/">my newsletter</a> to learn more about my process.</p><p><a href="https://alyssax.substack.com/embed">Alyssa X</a></p><p>I’m also open to opportunities — just send me an email at hi@alyssax.com! 💜</p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=de25c7be0458" width="1" height="1" alt=""><hr><p><a href="https://medium.com/women-make/how-i-built-a-macos-app-and-made-5000-in-a-week-de25c7be0458">How I built a MacOS app and made $5000+ in a week</a> was originally published in <a href="https://medium.com/women-make">Women Make</a> on Medium, where people are continuing the conversation by highlighting and responding to this story.</p>]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Building a Chrome Extension to Convert From Figma to Google Slides]]></title>
            <link>https://medium.com/women-make/building-a-chrome-extension-to-convert-from-figma-to-google-slides-b98de6603c43?source=rss-957f2a5d71e4------2</link>
            <guid isPermaLink="false">https://medium.com/p/b98de6603c43</guid>
            <category><![CDATA[google]]></category>
            <category><![CDATA[design]]></category>
            <category><![CDATA[chrome]]></category>
            <category><![CDATA[figma]]></category>
            <category><![CDATA[plugins]]></category>
            <dc:creator><![CDATA[Alyssa X]]></dc:creator>
            <pubDate>Fri, 06 Sep 2019 14:12:57 GMT</pubDate>
            <atom:updated>2022-12-26T01:07:29.297Z</atom:updated>
            <content:encoded><![CDATA[<figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*c0H-F2qKSBad5JZh6nRufQ.png" /></figure><blockquote>How I hacked together a <a href="https://chrome.google.com/webstore/detail/figma-to-google-slides/plebfmkclgnmenaemkgcnconhiodhakl">Figma plugin</a> without a plugin infrastructure</blockquote><p>A few months ago, while experimenting with the Google Sheets API to easily <a href="https://blog.usejournal.com/how-to-use-google-sheets-as-a-cms-or-a-database-f9d8e736fdce?source=---------5------------------&amp;gi=a137f88d3706">build websites with a back-end</a>, I was curious to see whether I could build something with other Google APIs. Being a designer at heart, I wanted to see what I could do with Google Slides, whether I could add some extra functionality, make it easier to use, or create some sort of integration.</p><p>Around the same time I had been particularly interested in the Figma API, and worked on a variety of small experiments, including a script to automatically turn a Figma frame into a RPG, a character customization implementation for a MMORPG, and much more. Because of that, I thought about combining both Figma and Google Slides to create something new — a way to easily <strong>create presentations straight from Figma</strong>, allowing the user to have more freedom over the design, and add a higher degree of complexity (while being more precise).</p><p><a href="https://alyssax.substack.com/embed">Alyssa X</a></p><h3>The Experiment</h3><p>With a solid concept and being rather familiarized with the APIs, I decided to give it a try. The fastest route was to create a simple script, without any sort of user interface, that would automatically render a set of frames within a Figma file, and export them into a Google Slides presentation, successively.</p><p>In order to do that, I had to follow these steps:</p><ol><li>Make a call to the <a href="https://www.figma.com/developers/api#get-files-endpoint"><strong>GET File</strong></a> Endpoint of the Figma API to get a list of all the node IDs for the different frames within the first page of the Figma file (for the sake of simplicity).</li><li>Call the <a href="https://www.figma.com/developers/api#get-images-endpoint"><strong>GET Image</strong></a> Endpoint using the previously retrieved node IDs to generate an exported image of each one of the frames (through a temporarily accessible URL).</li><li>Using the <a href="https://developers.google.com/slides/reference/rest/v1/presentations/batchUpdate"><strong>batchUpdate method</strong></a> of the Google Slides API, create a new slide and set the respective background image for each one of the frames from Figma.</li></ol><p>I quickly <a href="https://github.com/alyssaxuu/figma-to-google-slides/blob/master/Minified%20Version/index.php">put it together using PHP</a>, and as soon as it worked, I shared it on Twitter for everyone to see. To my surprise,<strong> it was a hit</strong>.</p><h3>Alyssa X on Twitter</h3><p>I decided to play around with the @figmadesign &amp;amp; @google slides API ✨ Made a script that converts frames from Figma into slides of a Google Slides presentation, quickly and effortlessly 📽️ A great way to make really pretty presentations 💄 Should I make a guide? 👀 cc @zoink https://t.co/feNjr4GyY7</p><p>Being extremely excited about how much people loved my little experiment, I decided I had to go a step further, not only sharing my script, but creating a product out of it that people could use to make beautifully-designed presentations.</p><h3>Reverse Engineering Figma (somewhat)</h3><p>As soon as I started brainstorming how to create a simplified version for people to use, I realized there had to be a UI for the users to interact with, somewhere, so that they could convert their frames into a presentation.</p><p>The easiest way to go about it would have been to create a website where users could insert their Figma file URL, authenticate both with Google and Figma, and then insert their Google Slides URL. I felt this was both counterproductive (which was against the spirit of the project) and not very contextual, so I had to come up with something better.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*kDnnIX4DDzaUX9L_1CZn3g.gif" /><figcaption>“Reverse engineering” Figma (as in, using inspect element to gather components &amp; see their hierarchy).</figcaption></figure><p>Since the action was going to happen in Figma, I wanted to have a way for the tool to be there, whatever it took. At the time <a href="https://www.figma.com/blog/introducing-figma-plugins/">Figma Plugins</a> were non-existent, and there were few attempts to create external integrations with the platform, but I still wanted to have my utility be part of Figma, a way or another, and I figured it could be done through a <strong>Chrome Extension </strong>— I would be injecting JavaScript into the Figma directly, while “reverse engineering” Figma to dig into the UI components (in order to have create the interface for my own utility) &amp; inject the different elements in the right places.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*OjQ4Ye-8qkzioUiOVfYGOA.gif" /><figcaption>The “reverse engineering” method led to some rather long strings to replicate different elements within Figma.</figcaption></figure><p>Basically, using inspect element (and some patience), I started looking for components I could reuse and trying to place them around the page. I decided to add an extra button on the toolbar to trigger the utility (by duplicating one of the divs and appending it to the end with <em>insertAdjacentHTML </em>in JavaScript), and for the tool itself, I just reused parts of the “Share” pop up so that the user could insert the Google Slides URL and press a button to convert, identifying the different class names being used to generate the elements. That way not only the tool was integrated within Figma itself, but it was following its own design system.</p><h3>Alyssa X on Twitter</h3><p>Reverse engineered @figmadesign&#39;s UI &amp;amp; implemented my Figma to @Google Slides converter in the top bar 🛠️ Trying to tweak the onboarding, pop up, &amp;amp; even the icon, so I appreciate your feedback! 😊 Will release a @googlechrome extension eventually so you can use it too! 🎁 https://t.co/PrIg8bfiEU</p><p>At that point, I had a very basic UI which was not only lacking functionality (easily signing in with Figma &amp; Google), but also didn’t have a very solidified design, so I had to do something about it.</p><h3>The Chrome Extension</h3><p>To work on the final product, I first had to determine what would be the onboarding. For the extension to work, I needed the user to sign in to Google (and give the tool the required permissions to edit a Google Slides project), as well as sign in to Figma to use the API.</p><p>I didn’t want this process to be a nuisance to the user, so I made it a one-time thing (when you first install the extension) through a Google Sign In button, and by having the user insert a personal Figma API key. Unfortunately I could not do it through Figma Oauth2 as it couldn’t be embedded in an extension, and it needed to be in a page.</p><p>Once I had figured out all the different steps, I designed the popup (with all of its states) in Figma itself, following their own style as to seamlessly blend with the interface.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*ll1lH7-Px-l2770wwsd80Q.gif" /><figcaption>The different pop up states for the extension, which I designed in Figma.</figcaption></figure><p>With the design for the plugin finished, I just had to implement it into the extension, so that I could create an onboarding flow for a new user, as well as show all the different errors that could be triggered (such as a wrong Figma key, a wrong Slides URL/unauthorized, no frames available to convert, and more).</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/800/1*ejD85TqmW0shHGAMMRGftQ.gif" /><figcaption>The onboarding flow for the extension, showcasing the different steps, and an error for an invalid URL.</figcaption></figure><p>Having completed the development of the extension, and being quite satisfied with the result, I was <strong>ready to release it to the public.</strong></p><h3>The Launch</h3><p>In anticipation for the launch, I wanted to make sure everything was going to work, so I wanted to do a private beta test of the utility, which was extremely helpful as not only were many bugs spotted that had gone unnoticed by me beforehand, but I also received a lot of great feedback from people who had ideas on how to improve the tool and make it even more useful.</p><p>Around the same time, and to guarantee that the script would work under different circumstances, I created a <a href="https://studiosnoon.com/figmaslides/">landing page for the extension</a> where users could try out a live demo on the site (before the extension had actually been launched), and companies could reach out to get early access.</p><p>Some weeks later, I decided the extension was good enough for a public launch, so I put it in the <a href="https://chrome.google.com/webstore/detail/figma-to-google-slides/plebfmkclgnmenaemkgcnconhiodhakl">Chrome Web Store</a> for everyone to get for free. It got a mixed reception in launch due to some issues with the conversion itself and the tool itself now showing in the UI (which surprised me after all the testing I had done beforehand), but I managed to tweak it and overcome the issues, growing to over 1200 users, and being featured in the <a href="https://www.figma.com/resources/extensions-and-apis/figma-to-google-slides/">Figma Community Resources Hub</a> (as well as in their newsletter).</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*4_GkgXfzQFfKGpDq4nLkJA.gif" /><figcaption>The Chrome Extension in action, showcasing the conversion of a pitch deck from Figma to Google Slides</figcaption></figure><p>To my surprise, through emails and tweets I had been receiving, my extension started to be used not only by individuals who wanted to play around with the tool, but by speakers, design teams within companies, and even startups for making pitch decks (as showcased in the GIF above — provided by Hamza Ouazzani, for his startup <a href="https://www.spotangels.com/">SpotAngels</a>), announcements, and more.</p><h3>Some final notes</h3><p>After the (personal) success of the extension, and seeing all the possibilities to create other Figma integrations (or within Google Slides itself), I decided to <a href="https://github.com/alyssaxuu/figma-to-google-slides">open source the entire extension</a> in GitHub (including the initial PHP file). While I was developing this tool, I noticed that there were few resources available to help people easily integrate the Google API within a Chrome Extension, so I hope the source code of this project with my small guide can help (or I could make an article specifically on creating Chrome extensions with the Google API…).</p><p>Now that Figma has plugin support, building an integration like this one should be a lot easier, but unfortunately being quite busy I don’t think I’m going to port it into the ecosystem. Would be more than happy if anyone wanted to give it a try though!</p><p>Finally, if you want to view another project I’ve built using the Figma API (which is also open source), feel free to check out my <a href="https://alyssax.com/x/platformer/">Figma Platforming Engine</a> for creating fun platforming games without code. I’m happy to answer any questions related to the Figma to Slides extension or on using the API. If you’d like to talk, do not hesitate to reach out to me at hi@alyssax.com or through <a href="http://twitter.com/alyssaxuu">Twitter</a> 💜</p><p><a href="https://alyssax.substack.com/embed">Alyssa X</a></p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=b98de6603c43" width="1" height="1" alt=""><hr><p><a href="https://medium.com/women-make/building-a-chrome-extension-to-convert-from-figma-to-google-slides-b98de6603c43">Building a Chrome Extension to Convert From Figma to Google Slides</a> was originally published in <a href="https://medium.com/women-make">Women Make</a> on Medium, where people are continuing the conversation by highlighting and responding to this story.</p>]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Building a Web-Based Motion Graphics Editor]]></title>
            <link>https://medium.com/women-make/building-a-web-based-motion-graphics-editor-bd070f8db795?source=rss-957f2a5d71e4------2</link>
            <guid isPermaLink="false">https://medium.com/p/bd070f8db795</guid>
            <category><![CDATA[product-design]]></category>
            <category><![CDATA[animation]]></category>
            <category><![CDATA[mvp]]></category>
            <category><![CDATA[entrepreneurship]]></category>
            <category><![CDATA[design]]></category>
            <dc:creator><![CDATA[Alyssa X]]></dc:creator>
            <pubDate>Sat, 15 Jun 2019 15:10:40 GMT</pubDate>
            <atom:updated>2022-12-26T01:07:06.094Z</atom:updated>
            <content:encoded><![CDATA[<figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*m2-EdlDBBN2k7cIpR80d6w.png" /></figure><blockquote>What would a modern motion graphics editor look like?</blockquote><p><strong><em>Update:</em></strong><em> Years after writing this article I ended up launching </em><a href="https://motionity.app/"><em>Motionity</em></a><em>, a motion graphics editor that is a mix between After Effects and Canva:</em></p><h3>Alyssa X on Twitter: &quot;Create animated videos in your browser like never before 🎥Motionity is a free &amp; open source motion graphics editor for the web 🙌 Browse assets, add keyframes with easing, mask layers, apply filters, text animations, Lotties, audio, and much more.👉 https://t.co/OHd7mEeNCn pic.twitter.com/2tc32xUf0A / Twitter&quot;</h3><p>Create animated videos in your browser like never before 🎥Motionity is a free &amp; open source motion graphics editor for the web 🙌 Browse assets, add keyframes with easing, mask layers, apply filters, text animations, Lotties, audio, and much more.👉 https://t.co/OHd7mEeNCn pic.twitter.com/2tc32xUf0A</p><p>Design tools are all the rage these days, with new and rising products within prototyping (<a href="https://www.invisionapp.com/studio">InVision Studio</a>), version control (<a href="https://www.abstract.com/">Abstract</a>), collecting &amp; giving feedback (<a href="https://usepastel.com/">Pastel</a>), creating mockups (<a href="https://artboard.studio/">Artboard Studio</a>), design-centric website builders (<a href="https://webflow.com/">Webflow</a>), collaborative design tools (<a href="http://figma.com/">Figma</a>), and many more. Despite that, there’s still an area within design which hasn’t had much innovation, and is still rather monopolized — <strong>motion graphics</strong>.</p><p>Motion graphics &amp; animation are used in a large range of scenarios, be it for videos, teasers, web interactions, pitches, and much more. And yet, your only option is to use Adobe After Effects if you want to have complex animations and motion off-rails.</p><p>I had this realization earlier this year, which led me to start developing a HTML5 web-based motion graphics tool, easy to use and affordable, as an alternative to Adobe After Effects. This was the process.</p><p><a href="https://alyssax.substack.com/embed">Alyssa X</a></p><h3>The Minimum Viable Product</h3><p>Being a rather ambitious project, outside of my comfort zone development-wise, I decided to go for an unusual approach.</p><p>Instead of starting by studying the concept, designing its interface, flows, gathering feedback, and more, I got straight into the action by implementing the basic features a motion graphics editor needs to work , and ensuring that I could put together a <strong>MVP</strong> (minimum viable product) by myself. I am always wary of the time projects take (my time is limited, as well as my resources), and I would rather determine their viability early on, than be surprised midway through its development.</p><p>Within 3 days I had managed to put together a renderer through HTML5 Canvas, allowing me to hard-code animations in JavaScript and export as a GIF or image sequence by getting the data from each frame. A few days later I put together the timeline from scratch (there’s almost no JavaScript timeline libraries out there!), together with some basic layering (I began by being able to create &amp; animate textboxes, later I implemented basic image &amp; footage import &amp; animation).</p><h3>Alyssa X on Twitter</h3><p>Decent progress on my web-based video editor ✨ Keeping its interface as simple as possible, while being a powerful tool for all sorts of content 💁‍♀️- pitches, teasers, ads, @dribbble shots, @youtube videos, or any kind of motion graphics project. The @figmadesign of video? 🤔 https://t.co/nKnvXM1YbG</p><p>It was all going incredibly well, having been able to develop many complex features in a rather short timeframe (except for some bugs that took a while to fix), and even having created several animations with it (I actually use my tool versus After Effects for animating GIFs because of the direct export to GIF feature). Because of that, I decided it was time to get back to square one, having proven that my idea worked.</p><h3>Designing a Better Motion Graphics Tool</h3><p>At this point, I had to start from the beginning. I knew I could develop the editor, which was my main concern to get it off the ground, but there was still a lot of work to do. I began by determining its principles and the areas of focus of the tool. Here are some of the main takeaways:</p><ul><li><strong>Accessible.</strong> This means many things — being affordable, not platform-dependant, and simple enough to use (at least compared to a tool like Adobe After Effects).</li><li><strong>Specialized.</strong> In order to stand out and more easily get a place in the market (the do-it-all tool already exists), the editor would have to be specialized in 2D motion graphics.</li><li><strong>Modern. </strong>Considering the field hasn’t had much innovation over the past years, introducing new features and an up-to-date design would be key to the success of the tool.</li><li><strong>Connected. </strong>A great way to maintain a user-base when it comes to design tools is to create a network. An asset store with user-created resources &amp; templates, as well as plug-in support would go a long way to ensure people stay in the platform.</li></ul><p>After doing that, I had a much clearer picture of what I wanted to make, and it led me to collecting direct feedback from potential users to ensure I was building something people really wanted, which really helped me polish the concept.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*a_WD6BtVvhNkZd-TA9w6pg.png" /><figcaption>The UI of Adobe After Effects can be quite overwhelming to a new user.</figcaption></figure><p>Since what I was building would be a direct competitor to Adobe After Effects, I also studied it in-depth. I had the advantage of being very familiarized with the tool, having used it frequently for interactions, animations, and more, so I was aware of several small and big inconveniences present in the workflow for the projects I was working on, such as being unable to export as GIF, having to switch between a lot of tabs to go through compositions, not seeing which keyframes had change between them and which were “static” (also brought up <a href="http://www.sandervandijk.tv/after-effects-features">here</a>), and overall being overwhelmed with lots of panels and buttons in the interface (many of which aren’t even used for 2D motion graphics).</p><p>Now all I had to do was to solve those issues and put together a concept combining all the ideas and features I had come up with.</p><h3>Sketching and Wireframing</h3><p>When it comes to designing the interface of a product, I tend to always follow the same process. I start by going off my laptop and writing everything down in my notebook. This helps me focus — sometimes I’ll spot a flaw or inconsistency in my ideas that I wouldn’t have noticed otherwise. It’s also a great way for me to be inspired and be more creative, which can lead to coming up with new ideas and new directions that could greatly improve a product.</p><p>Once I’ve filled my notebook with notes, I can start sketching out the layout of the product. For this project, I started by outlining the different areas of the editor (timeline, canvas, toolbar, layer settings…), through simple blocks. This led to different iterations which I used as a base to implement specific elements, such as the list of layers for the timeline, buttons for the toolbar, and sections for the layer settings panel. <strong>It works a bit like a puzzle</strong> — trying to find a way to make everything fit and work together, while following basic design principles. After I felt like I had enough iterations, I moved on to digitalizing everything.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*k-5_E17S0m2ZKD8Wd6FnZQ.png" /><figcaption>Some of the layout and components ideas I had in the brainstorming phase.</figcaption></figure><p>My tool of choice for designing interfaces is <a href="http://figma.com/">Figma</a>, being in the web, with collaborative features (helpful to share my work with others and showcase it live) and a simple way to collect feedback. Before designing anything, I always start by gathering inspiration from all over the web (sometimes I do this in the sketching process as well). This allows me to explore different distributions, styles, color palettes, and more.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*6xUS0tRpix-82md2dYxxBg.gif" /><figcaption>The result of iterating over different layouts and styles.</figcaption></figure><p>I went through a lot of iterations to end up with a cohesive and intuitive editor, having to re-organize entire sections and finding workarounds to make the interface less cluttered while still being easy to understand.</p><h3>The Final Product</h3><p>After testing and showing different versions of the editor to potential users while collecting feedback, I managed to create a UI true to my vision and the principles I had initially established for the product.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/800/1*3Qaiv6oYiUTu4N1st4DK1Q.gif" /><figcaption>The finished interface for the editor, true to the product’s principles.</figcaption></figure><p>I went for a light interface as opposed to Adobe After Effects’ dark UI in order to make it feel approachable and less cluttered, which in turn made it feel way more friendly to beginners. Aside from that, since I decided to build the product in the niche of 2D motion graphics, I added a panel on the right with different settings to style the layers, similar to other vector editing tools.</p><h4>Timeline area</h4><figure><img alt="" src="https://cdn-images-1.medium.com/max/800/1*_PSUPvM0IiVlYG7Kvw79ug.gif" /><figcaption>In order not to overwhelm the user, the timeline is extremely simple and intuitive.</figcaption></figure><p>The timeline of the editor is similar to the one in Adobe After Effects, but it has its own differences. I wanted to ensure the users didn’t feel overwhelmed by it, so I simplified it. For example, in the layer section, I only show the icon determining the layer type (with a customizable color) and the label. To see more settings, the user can hover to reveal buttons to hide, lock, or add a parent to the layer. Another difference is the heading of this section, which includes a search feature (particularly useful when working on big projects with lots of layers).</p><p>One small detail that greatly improves the workflow is in the keyframe area — <strong>displaying change between keyframes</strong> through a thin line. This is helpful to move more easily throughout the timeline, since the user can see the periods of time where a layer is static or transitioning, instead of having to check by previewing parts of the animation.</p><h4>The Canvas</h4><figure><img alt="" src="https://cdn-images-1.medium.com/max/800/1*YD0JFXeUadPwFJ_ilVr4GA.gif" /><figcaption>One of the key features of the editor is the scenes functionality, which speeds up the workflow.</figcaption></figure><p>The canvas of the tool is rather unusual for an animation tool. Taking inspiration from editors such as Figma or Sketch, instead of seeing only one scene at once (in After Effects, it’s called a composition), you have them all in sight. Because of that, you don’t need to switch back and forth between tabs to compare the changes, but can work in context and more efficiently animate the different sections of the project. The timeline automatically changes depending on the scene the user is working on, showing the respective layers.</p><h4>Toolbar &amp; settings</h4><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*QUFeNEWeQyd05UXY_FRbIA.png" /><figcaption>The panels and toolbars within the editor follow a consistent style, and work in modules.</figcaption></figure><p>I added a toolbar on the left for multiple reasons. I wanted to ensure there was enough vertical space for the canvas, since the timeline area already takes a big chunk, and I needed to have a top bar with some menus and settings. I also needed to distinguish between tools and other types of actions, which I could do very easily vertically by putting the tools at the top, and the rest at the bottom. As to make importing files easier, I included a quick shortcut in the toolbar, together with the project settings and a button to access the resource store (for community-made assets, templates, and more).</p><p>As per the right panel of the editor, I prioritized simplicity and a modular style. Because of that, users can collapse sections and reorder them however they like, depending on what they use the most. The panel has 2 tabs, one for the layer being edited at the time, and another one for the scene in general.</p><h3>Okay, but where’s the tool?</h3><p>Having managed to both develop the core functionality of the motion graphics editor and design a cohesive interface for it, I was on my way to actually build the entire tool, and make it happen.</p><p><strong>At least, that’s how I expected it to go.</strong> A project of this scope takes time, as well as resources, which I did not have. My plan was to build the product in 6–12 months (for an initial MVP), dedicating to it exclusively, but life got in the way, and I couldn’t put the time towards the project anymore, since I had to prioritize freelance work to make ends meet. In the end I decided to keep the project on hold, and instead go after a full-time job, focusing on smaller projects to expand my portfolio.</p><p>I still don’t have a new plan for the motion graphics editor — I’ve got a working version (as I explained in the MVP section of this article), and I could either open source my work to date, build a smaller version (e.g. narrowing it down to a very specific area such as simple animated GIFs), or keep it for the future, when I am in a position to build the whole thing. Ideas welcome!</p><p>I am also open to opportunities — just send me a mail at hi@alyssax.com! 💜</p><p><a href="https://alyssax.substack.com/embed">Alyssa X</a></p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=bd070f8db795" width="1" height="1" alt=""><hr><p><a href="https://medium.com/women-make/building-a-web-based-motion-graphics-editor-bd070f8db795">Building a Web-Based Motion Graphics Editor</a> was originally published in <a href="https://medium.com/women-make">Women Make</a> on Medium, where people are continuing the conversation by highlighting and responding to this story.</p>]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[How to use Google Sheets as a CMS or a database]]></title>
            <link>https://medium.com/@alyssax/how-to-use-google-sheets-as-a-cms-or-a-database-f9d8e736fdce?source=rss-957f2a5d71e4------2</link>
            <guid isPermaLink="false">https://medium.com/p/f9d8e736fdce</guid>
            <category><![CDATA[website]]></category>
            <category><![CDATA[google]]></category>
            <category><![CDATA[development]]></category>
            <category><![CDATA[tutorial]]></category>
            <category><![CDATA[makers]]></category>
            <dc:creator><![CDATA[Alyssa X]]></dc:creator>
            <pubDate>Sat, 19 Jan 2019 11:09:25 GMT</pubDate>
            <atom:updated>2022-07-01T21:30:51.812Z</atom:updated>
            <content:encoded><![CDATA[<p>Over the past week, I shared multiple demos in Twitter where I showcased different sites powered by Google Sheets. Several people were curious as to how I had built them, and I promised writing a Medium article (my first one, please be kind! 💜), so here it is!</p><p>Before I get into the guide, I want to explain why this may be useful or what possible uses this could have. Being an alternative to a CMS or database, it obviously has the same capabilities as an equivalent, but being Google Sheets, there are several added advantages. Let me list a few:</p><ul><li>Easily edit the data from Google Sheets ✍️ (super straight-forward)</li><li>Accessing the sheet from any device (multiplatform)</li><li>Sharing the sheet with other people (who can also contribute)</li><li>Backups &amp; version history (some databases don’t have this!)</li><li>Flexibility to grow &amp; reduce the database by adding new columns on the go</li></ul><p>In terms of possible uses, it can obviously do absolutely anything you can think of, but here’s some that could be particularly interesting for Google Sheets:</p><ul><li>Running a blog (Using Google Sheets as the CMS)</li><li>Creating a product review website ✨</li><li>Making a list of people, websites, or any sort of content that could be contributed by users / moderators directly through the sheet</li><li>Storing information from a form (fully customizable, w/o Google Forms)</li><li>Tracking finances or stats in sheets &amp; outputting them in a website 📊</li></ul><p>With everything cleared up, here’s how you can read and write from Google Sheets through your website (&amp; use it as a database or content management system!). I will explain how to implement the script in PHP, but in <a href="https://developers.google.com/sheets/api/guides/concepts">Google’s documentation</a> you can find some information to build it in any other language.</p><h3><strong>1. Create a sheet</strong></h3><p>The first step is simple — just make a new sheet in Google sheets &amp; make sure you keep it open or save the URL. You don’t have to make the sheet public whatsoever, so your data will be safe there! 🔒</p><h3>2. Set up the Google API</h3><p>In order to connect with your sheet, you need to use the Google API. Go to the <a href="https://console.cloud.google.com/apis/">Google API Console</a> and click on “Library” in the left menu. You will be able to choose from a range of APIs within Google — in this case, you need to look for “Google Sheets API” and click on “Enable”.</p><p>Now you need to create the credentials to authenticate &amp; access the data from your sheet 🔑. Go back to the dashboard, and click on “Credentials” in the sidebar. If it’s your first time here, you will be asked to create a new project. Click on “Create”, give it a name, and proceed. Once done, you will finally be able to create the credentials. Click on “Create credentials”, and select “Service account key” from the dropdown.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*hHZB4goBMEl0xigrdGXSlA.gif" /><figcaption>The different steps to create your service key</figcaption></figure><p>You will be redirected to a menu where you can create the service key. You can give it any name, select a role (ensure that the role you select has read &amp; write permissions: Project&gt;Owner is a good option), and create a unique email address. Make sure that the key type is JSON, and click on “Create”. The key will be automatically downloaded to your computer — save it inside your server in an accessible place, so you can import it later to your code.</p><p>The email address is very important, and you have to share the previously created sheet with it, giving it read &amp; write permissions. In order to do that, just go back to the sheet, click on “Share”, and under “People” just paste the email address, select “Edit”, and click on done.</p><h3>3. Authentication to the sheet</h3><p>In order to connect to the sheet, we’ll be using a simple PHP script, your service key and the sheets URL. To make things easier, I am using the Google API PHP Client library that <a href="https://github.com/googleapis/google-api-php-client">you can find in GitHub</a> 💁‍♀️. You can install it using composer (follow the guide in the GitHub repository), but if you don’t have it set up, or don’t know how it works, you can download the latest release <a href="https://github.com/googleapis/google-api-php-client/releases">from this page</a>, save it inside your server (in my case it’s in the “google” folder), and insert the following line on top of your script:</p><pre>require_once &#39;google/vendor/autoload.php&#39;;</pre><p>Once you have imported the library, you simply have to add the following snippet to your code to do the authentication:</p><pre>$client = new \Google_Client();<br>$client-&gt;setApplicationName(&#39;YOURAPPNAME&#39;);<br>$client-&gt;setScopes([\Google_Service_Sheets::SPREADSHEETS]);<br>$client-&gt;setAccessType(&#39;offline&#39;);<br>$client-&gt;setAuthConfig(__DIR__ . &#39;/servicekey.json&#39;);<br>$service = new Google_Service_Sheets($client);<br>$spreadsheetId = &quot;YOUR_SHEET_ID&quot;;</pre><p>You have to tweak the following parts from the snippet:</p><ul><li><strong>‘YOURAPPNAME’</strong>: The name of your application, it can be anything (no relation with the name of your project in the Google API Console!)</li><li><strong>‘/servicekey.json’</strong>: The directory where you stored the service key that was downloaded previously</li><li><strong>‘YOUR_SHEET_ID’</strong>: The ID of your sheet. For example, in this example sheet, <a href="https://docs.google.com/spreadsheets/d/1BxiMVs0XRA5nFMdKvBdBZjgmUUqptlbs74OgvE2upms/edit">https://docs.google.com/spreadsheets/d/1BxiMVs0XRA5nFMdKvBdBZjgmUUqptlbs74OgvE2upms/edit</a>, the ID is the part that goes from /d/ to /edit, so it would be “1BxiMVs0XRA5nFMdKvBdBZjgmUUqptlbs74OgvE2upms”.</li></ul><h3>4. Reading from the sheet</h3><p>With the authentication set up, you can now access the data from your sheet freely 🧐. In order to read from the sheet, there are several ways to go about it (&amp; explained more in depth <a href="https://developers.google.com/sheets/api/guides/concepts">in the API documentation</a>), but I will explain the basics to read a specific range or the entire sheet.</p><p>If you want to read a specific range from the sheet, you need to add the following snippet to the script (after the authentication):</p><pre>$range = &#39;SHEET_NAME!A1:A5&#39;;<br>$response = $service-&gt;spreadsheets_values-&gt;get($spreadsheetId, $range);<br>$values = $response-&gt;getValues();<br>if (empty($values)) {<br>   print &#39;No data found.\n&#39;;<br>} else {<br>   foreach ($values as $row) {<br>      for ($i = 0; $i &lt; sizeof($row); $i++) {<br>          echo $row[$i].&#39;\n&#39;;<br>      }<br>   }<br>}</pre><p>Here is a breakdown of the script:</p><ul><li><strong>‘SHEET_NAME!A1:A5’</strong>: This should include the name of your sheet and the desired range. The name of the sheet tends to be Sheet1 by default, but if you are unsure, you can always see what it is in the bottom left of your sheet. As per the part after the “!” (which you have to keep, so if your sheet is called Sheet1, put “Sheet1!”), you simply have to specify a range from a cell to another, just like you would do in Google Sheets for other purposes.</li><li><strong>Foreach loop</strong>: This part simply iterates through the generated array and outputs each cell individually. From that point, you are free to use the data you retrieve for any purpose.</li></ul><p>Alternatively, if you want to read the entire sheet, simply replace the range with the name of the sheet, likewise (without the exclamation mark):</p><pre>$range = &#39;SHEET_NAME&#39;;</pre><h3>5. Writing to the sheet</h3><p>Updating or writing values in the sheet is also quite straight-forward, similar to what I previously explained for reading 📝. I will show you how to update or add values to a specific range within a sheet, and how to add new rows.</p><p>Let’s begin by working within a range. Here is the script:</p><pre>$range = &#39;SHEET_NAME!A1&#39;;<br>$body = new Google_Service_Sheets_ValueRange([<br>    &#39;values&#39; =&gt; &#39;YOUR_VALUE&#39;<br>]);<br>$params = [<br>    &#39;valueInputOption&#39; =&gt; &#39;USER_ENTERED&#39;<br>];<br>$result = $service-&gt;<br>spreadsheets_values-&gt;update($spreadsheetId, $range,<br>$body, $params);</pre><p>As you can see, we are using some parameters that were present in the reading process.</p><ul><li><strong>‘SHEET_NAME!A1’</strong>: Works the same way as previously explained in the reading section.</li><li><strong>‘YOUR_VALUE’</strong>: The value that you want your cell to have. Keep in mind that it is an array, so you may add as many values as cells you have selected within the previous range.</li></ul><p>Now, let’s see how we can easily add a row to a sheet:</p><pre>$range = &#39;SHEET_NAME&#39;;<br>$valueRange= new Google_Service_Sheets_ValueRange();<br>$valueRange-&gt;setValues([&quot;values&quot; =&gt; [&#39;YOUR_VALUE1&#39;, &#39;YOUR_VALUE2&#39;]]); <br>$conf = [&quot;valueInputOption&quot; =&gt; &quot;RAW&quot;];<br>$ins = [&quot;insertDataOption&quot; =&gt; &quot;INSERT_ROWS&quot;];<br>$service-&gt;spreadsheets_values-&gt;append($sheet, $range, $valueRange, $conf, $ins);</pre><p>It is very similar to the previous script. Here’s the parameters you need:</p><ul><li><strong>‘SHEET_NAME’</strong>: The name of your sheet</li><li><strong>‘YOUR_VALUE1’ </strong>(‘YOUR_VALUE2’, ‘YOUR_VALUE3’…): The values you want to append to the sheet. You may add more into the array — they will be added one next to another in the new row.</li></ul><p>This was a simple guide to work with Google API for Sheets in PHP, hopefully it was useful! Feel free to ask any question below if you get stuck somewhere or have feedback 😊</p><p>Now, some of you might be a bit confused — didn’t I mention making GitHub Pages or any static website platform dynamic? It’s not like you can add PHP files to GitHub Pages! 😫</p><p>Well, you certainly can’t add PHP to GitHub Pages, BUT (!) you still have a couple of options:</p><ul><li>Using JavaScript to connect with the Google API (<a href="https://developers.google.com/sheets/api/guides/concepts">explained in the documentation</a>). The problem with that is that your API keys will be exposed, as well as your sheets URL. If you are working with a public API key or a public sheet, this is not a big deal, but the examples I showcased required the privacy factor, so this is not a good idea.</li><li>Hosting the PHP script in Heroku or another server &amp; making calls to it using AJAX in GitHub Pages. This can be completely secure by not only keeping the API key &amp; sheets URL in that server, but also only accepting calls from a specific domain (in this case, your own website within GitHub Pages)</li></ul><p>But, what if you don’t have a server (if you want something proper it can be costly) or don’t know how to set it up? 🤔</p><p>No problem! These past weeks, at the same time that I’ve been working on the different demos, I’ve been developing a platform that allows you to submit your sheets ID, API keys, allowed URL (your GitHub Pages or static domain) and generates the code you can embed to your site to read or write from the sheet. It isn’t out yet (I want to ensure it’s polished!) but I also would like to write a little bit about how to make this yourself (open sourcing the code) so you don’t have to use my platform whatsoever, and can set it up in your own server.</p><p>I will also hopefully find the time to make some more articles with some examples &amp; guides on how to create some of the demos I made. So far I have a form &amp; blog in mind, but you are free to make suggestions as well — I really appreciate it! Thanks for reading!</p><figure><a href="https://usejournal.com/?utm_source=medium.com&amp;utm_medium=noteworthy_blog&amp;utm_campaign=guest_post_image"><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*f2IVAl0TbsfES9cFGYr40g.png" /></a></figure><p>📝 Read this story later in <a href="https://usejournal.com/?utm_source=medium.com&amp;utm_medium=noteworthy_blog&amp;utm_campaign=guest_post_read_later_text">Journal</a>.</p><p>🗞 Wake up every Sunday morning to the week’s most noteworthy Tech stories, opinions, and news waiting in your inbox: <a href="https://usejournal.com/newsletter/?utm_source=medium.com&amp;utm_medium=noteworthy_blog&amp;utm_campaign=guest_post_text">Get the noteworthy newsletter &gt;</a></p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=f9d8e736fdce" width="1" height="1" alt="">]]></content:encoded>
        </item>
    </channel>
</rss>