Add a YouTube stats widget to your iPhone with JavaScript
Tags: javascript, showdev, scriptable, youtube
Published: 2021-01-26 03:45:01

In this article, I'll be showing you how to add a YouTube widget to your iPhone that pulls in a couple of stats from your YouTube channel—total subscribers and total views.

## What will it look like on my phone?!

Great question, here's a screenshot of the widget on my phone with my *excellent* channel stats 🥳

![Screenshot of iPhone Home Screen with YouTube widget](https://dev-to-uploads.s3.amazonaws.com/i/731hka6ztpzz97z7e97m.png)

Looks nice right? You want one on your phone too, you say? Well let me show you how!

## What it won't do

Wait...before we get started let me tell you what the widget won't do for you. It **won't** create new videos for you. It **won't** give you more subscribers. It **won't** make you a YouTube sensation.

Unfortunately, you'll have to still put in the work to make all your YouTube dreams come true.

What the widget *could do* is give you a little motivation every time you look at your iPhone's Home Screen to keep creating and putting your work out into the world.

I hope you still want this widget on your phone...I just wanted to set the right expectations first 😬

## What you'll need to get started

In order to get this widget on your phone and working correctly you'll need four things.

1. You'll need an iPhone with iOS 14—the first version of iOS where widgets appeared.
2. An app called [Scriptable](https://scriptable.app).
3. A Google API key—you can [follow instructions here](https://developers.google.com/youtube/v3/getting-started) to set up an account and get one.
4. A little patience as there's some code involved. No worries if you're not a coder, I'll do my best to guide you along and make it as not scary as possible.

Once you've got all four of the items in the list above, it's time to grab your YouTube channel ID.

## Where to find your YouTube channel ID

The easiest way to grab your YouTube channel's ID is to pull up the channel in your browser.

In the address bar, you should see,

```
www.youtube.com/channel/****
```

Where `***` represents your channel's ID.

![Screenshot of YouTube channel highlight the channel ID](https://dev-to-uploads.s3.amazonaws.com/i/2llwdksh52ui9heaxzs9.png)

Write your channel ID down or copy and paste it somewhere because you're going to need it in a little bit.

But wait Michael, I'm MKBHD and I've got a totally sweet short URL for my channel like this,

![Screenshot of MKBHD's YouTube channel](https://dev-to-uploads.s3.amazonaws.com/i/1nvw9lm66u8p7eopjkyq.png)

How do I get my channel's ID?

Glad you asked Marques!

This is how you find your channel's ID if you've got one of those fancy short URLs for your YouTube channel.

1. Click on any video in your channel
2. Hover over your profile's name on the video page, you'll notice that it's actually linking to your channel with the non-fancy, long obscure ID.

    ![Hover over YouTuber name to reveal channel ID](https://dev-to-uploads.s3.amazonaws.com/i/0d7c6k2h5j47b58qdu44.png)

3. Right click over your name and select the copy link and now you've got your channel URL with the ID. Throw away everything **but** the channel ID.

    ![Right click on name to copy the channel URL](https://dev-to-uploads.s3.amazonaws.com/i/ykhgi2e6yq0bklac9lbs.png)

## The code

Now comes the part where it might get a little scary if you've never touched code before, but I promise I'll try to make it as not scary as possible.

In this part we'll put some code into Scriptable and then use some of the things we've been collecting to finally get our widget set up.

1. Open up Scriptable and create a new script by pressing the `+` button in the top right hand corner.

    ![Tap on the top right plus symbol to create a new script](https://dev-to-uploads.s3.amazonaws.com/i/hkam9inf8cbnh5gqtp1l.png)

2. Copy and paste this code in there,

    ```javascript
    const apiKey = ""
    const channelID = ""
    const channelName = "My channel"
    
    if (config.runsInWidget) {
      const widget = await createWidget()
      Script.setWidget(widget)
      Script.complete()
    }
    
    async function getData (channelID, apiKey) {
      const url = `https://www.googleapis.com/youtube/v3/channels?part=statistics&id=${channelID}&key=${apiKey}`
      const r = new Request(url)
      const body = await r.loadJSON()
      return body
    }
    
    async function createWidget() {
      const widget = new ListWidget()
      
      let ytData = await getData(channelID, apiKey)
      ytData = ytData.items[0]
      
      const subscribers = widget.addText(abbreviateNumber(ytData.statistics.subscriberCount, 2))
      subscribers.font = Font.boldSystemFont(36)
      subscribers.centerAlignText()
      
      const subscribersLabel = widget.addText("Subscribers")
      subscribersLabel.font = Font.semiboldSystemFont(10)
      subscribersLabel.centerAlignText()
      
      widget.addSpacer()
      
      const viewsBlock = widget.addStack()
      viewsBlock.addSpacer()
      
      const viewsContainer = viewsBlock.addStack()
      viewsContainer.layoutHorizontally()
      viewsContainer.centerAlignContent()
     
      const viewSymbol = SFSymbol.named("play.fill")
      const viewImage = viewsContainer.addImage(viewSymbol.image)
      viewImage.tintColor = Color.white()
      viewImage.imageSize = new Size(12, 12)
      
      viewsContainer.addSpacer(4)
     
      const views = viewsContainer.addText(abbreviateNumber(ytData.statistics.viewCount))
      views.font = Font.semiboldSystemFont(20)
      views.centerAlignText()
      
      viewsBlock.addSpacer()
     
      const viewsLabel = widget.addText("Views")
      viewsLabel.font = Font.semiboldSystemFont(10);
      viewsLabel.centerAlignText()
      
      widget.addSpacer()
      
      let channelLabel = widget.addText(channelName)
      channelLabel.font = Font.semiboldRoundedSystemFont(10);
      channelLabel.centerAlignText()
      
      widget.addSpacer(2)
      
      let reloadStack = widget.addStack()
      reloadStack.layoutHorizontally()
      reloadStack.centerAlignContent()
      
      reloadStack.addSpacer()
      
      let reloadSymbol = SFSymbol.named("arrow.triangle.2.circlepath")
      let reloadImage = reloadStack.addImage(reloadSymbol.image)
      reloadImage.tintColor = Color.white()
      reloadImage.imageSize = new Size(8, 8)
      reloadImage.imageOpacity = 0.9
      reloadImage.centerAlignImage()
      
      reloadStack.addSpacer(2)
      
      let today = new Date()
      let updateTime = `${today.getMonth() + 1}/${today.getDate()} ${zeroPad(today.getHours())}:${zeroPad(today.getMinutes())}`
      
      let updateLabel = reloadStack.addText(updateTime)
      updateLabel.font = Font.semiboldRoundedSystemFont(8)
      updateLabel.textOpacity = 0.9
      updateLabel.centerAlignText()
      
      reloadStack.addSpacer()
        
      const startColor = new Color("#ff0000")
      const endColor = new Color("#e40000")
      const gradient = new LinearGradient()
      gradient.colors = [startColor, endColor]
      gradient.locations = [0.0, 1]
      widget.backgroundGradient = gradient
      
      return widget
    }
    
    // Credit: https://stackoverflow.com/a/32638472
    // Thanks to https://stackoverflow.com/users/1438550/d-deriso
    function abbreviateNumber(num, fixed) {
      num = Number(num)
      if (num === null) { return null; } // terminate early
      if (num === 0) { return '0'; } // terminate early
      fixed = (!fixed || fixed < 0) ? 0 : fixed; // number of decimal places to show
      var b = (num).toPrecision(2).split("e"), // get power
      k = b.length === 1 ? 0 : Math.floor(Math.min(b[1].slice(1), 14) / 3), // floor at decimals, ceiling at trillions
      c = k < 1 ? num.toFixed(0 + fixed) : (num / Math.pow(10, k * 3) ).toFixed(1 + fixed), // divide by power
      d = c < 0 ? c : Math.abs(c), // enforce -0 is 0
      e = d + ['', 'K', 'M', 'B', 'T'][k]; // append power
      return e;
    }
    
    function zeroPad(numToPad) {
      if (numToPad > 9) {
        return numToPad
      } else {
        return `0${numToPad}` 
      }
    }
    ```

3. Add your API key to the first line in the code that starts like this,

    ```
    const apiKey = ""
    ```
    
    You'll want to add the API key in between the two quotation marks `""`. Once you do, the first line of code should look something like this,
    
    ```
    const apiKey = "yourAPIKeyFromGoogle"
    ```

4. Add your channel key to the second line in the code that starts like this,
    
    ```
    const channelID = ""
    ```
    
    Again, you'll want to add the ID in between the two quotation marks `""`. Once you do, the second line of code should look something like this,
    
    ```
    const channelID = "yourChannelIDWeGrabbedEarlier"
    ```

5. And that's it for the coding portion! Now let's add just a little bit of flair by giving our script a name, icon and color. You can do this by pressing the icon in the bottom left corner of your screen.

    ![Tap on the icon to get to the script settings](https://dev-to-uploads.s3.amazonaws.com/i/2cynvw80tei1hmolg1dq.png)

    You'll get this screen where you can set a name, icon and color.
    
    ![You can change the name, icon and color of the script from this screen](https://dev-to-uploads.s3.amazonaws.com/i/f8crh76da8vnc55odt6a.png)

6. Now that you're done. Close the window and tap **Done** to exit our of your script. We're ready for the moment we've all been waiting for...the widget!

## The widget

In this section, I'll show you how to get the new Scriptable widget on your Home Screen. If you're already familiar with this process, feel free to skip over this step and go to the next section.

[To add the widget to your Home Screen](https://support.apple.com/en-us/HT207122) you'll want to do this.

1. Tap and hold anywhere on your Home Screen until the apps start to jiggle.

    ![Gif to show app jiggle on iOS Home Screen](https://dev-to-uploads.s3.amazonaws.com/i/z0cg7w94tnl4pnws6haq.gif)

2. Tap the plus `+` button in the top left hand corner,

3. Scroll down until you see Scriptable and tap it.

4. Select the small widget (which should be the default one shown) and tap **Add Widget**

5. Once the widget is added to your Home Screen, you'll see the widget display, *Select script in widget configurator*, tap the new widget and you should get the widget configurator.

6. Next to the label, *Script* tap **Choose** to select the new YouTube script you had added into the Scriptable. Once you've selected it, tap outside of the configurator to be taken back to your Home Screen.

    ![Photo of Scriptable configurator](https://dev-to-uploads.s3.amazonaws.com/i/v451wcy8a9hy9e4n60ms.png)

7. 🥳 do a little dance cause now you've got your very own YouTube widget on your Home Screen to go with you wherever you go. The widget is proof that your work is appreciated by viewers from all over!

## Get fancy

Now that you're able to see your channel's subscriptions and video views count, I hope it motivates you to keep putting out great videos to share with the world!

If you're feeling adventurous, try enhancing the widget in Scriptable to make it your own. With a little knowledge of JavaScript, some imagination and the incredible, well put [together doc](https://docs.scriptable.app), you can improve it to really match your personal brand.

![Screen shot of Michael's widget and a custom MKBHD widget](https://dev-to-uploads.s3.amazonaws.com/i/j8ro62hn8ikaa4a5028v.png)

If you're looking for customizations but can't be bothered with more code, you can [purchase the enhanced code](https://michaelsoolee.com/scriptable-youtube-widget/). The code comes with easy-to-follow instructions to add a custom logo and background to your YouTube widget.

---

Originally posted on [michaelsoolee.com](https://michaelsoolee.com/ios-scriptable-youtube-widget/).

Thanks for taking the time to read this article! If you'd like, I can send you similar articles to your email. [Click here to sign up](https://michaelsoolee.com/newsletter/).