Picture of Michael Lee

iOS Scriptable YouTube widget

Written on January 20, 2021

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

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.
  3. A Google API key—you can follow instructions here 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

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

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

  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

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

  2. Copy and paste this code in there,

     const apiKey = ""
     const channelID = ""
     const channelName = "My channel"
     const textColor = Color.white()
        
     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()
       subscribers.textColor = textColor
          
       const subscribersLabel = widget.addText("Subscribers")
       subscribersLabel.font = Font.semiboldSystemFont(10)
       subscribersLabel.centerAlignText()
       subscribersLabel.textColor = textColor
          
       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()
       views.textColor = textColor
          
       viewsBlock.addSpacer()
         
       const viewsLabel = widget.addText("Views")
       viewsLabel.font = Font.semiboldSystemFont(10);
       viewsLabel.centerAlignText()
       viewsLabel.textColor = textColor
          
       widget.addSpacer()
          
       let channelLabel = widget.addText(channelName)
       channelLabel.font = Font.semiboldRoundedSystemFont(10);
       channelLabel.centerAlignText()
       channelLabel.textColor = textColor
          
       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()
       updateLabel.textColor = textColor
          
       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

    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

  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 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

  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

  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, you can improve it to really match your personal brand.

Screen shot of Michael's widget and a custom MKBHD widget

If you’re looking for customizations but can’t be bothered with more code, you can purchase the enhanced code. The code comes with easy-to-follow instructions to add a custom logo and background to your YouTube widget.

If you've found this article help, consider buying me a slice of pizza 🍕