James Cridland

How I built the Podnews podcast pages

I was asked on Twitter to document how I built the Podnews podcast pages. So, here we are, then.

What are they?

I write a lot about podcasts, but there are very varying ways of linking to them: some have their own websites, while others just send an Apple iTunes link over. That’s fine if you have an Apple device, but over 75% of the world uses Android, including me. I wanted something a little more consistent: and especially something that would allow you to listen immediately instead of a complex subscribe journey.

So, I produced a look-up page, which queries the Apple Podcast data, and then one piece of code that produces this podcast page (or hundreds like them): https://podnews.net/podcast/1176327926

The Apple Podcast ID

The number at the end of the URL is the Apple Podcast ID, visible in any link to the Apple Podcast page. It’s a proprietary ID produced by Apple, but it’s very easy to find.

Apple has an API to look up more details about that ID, so the first thing I do is go and grab that data from https://itunes.apple.com/lookup?id=1176327926.

It won’t escape you that this API was really developed for music tracks, hence some of the words used within this result. Anyway, it contains a bunch of useful information like the name of the podcast and graphics. And it’s JSON, so PHP’s helpful json_decode function comes in here.

Apple iTunes helpfully also gives us the “feedUrl”, which is the RSS feed of the podcast. I then go and grab that for some additional information (primarily the link to the podcast’s website, and the audio). I use simplexml_load_file to load this in.

Armed with all that data, I can then build the page.

The page is built from…

I use the AMP framework to author Podnews; it’s a simple framework which is highly cacheable and contains many optimisations for speed. I then use Amazon Cloudfront to cache pages and elements, to make sure that the load on my server is very low and also to ensure speed for the viewer.

The image at the top of the page is produced by grabbing the podcast artwork, rotating and resizing it, placing it on a pre-built background, and then serving that as one cached file. I use a PHP image library to achieve this. It’s then cached by Amazon Cloudfront for a very long time, so hopefully my server rarely needs to do this work: it’s very processor intensive. (I could probably achieve similar with two images and CSS).

The audio player is standard HTML5 audio code, with preload switched-off so that it doesn’t interfere with podcast stats. It’s an amp-iframe: that enables me to run bespoke JavaScript for the player (which is forbidden by AMP), and secondly allows me to cache the main podcast page quite heavily while only caching the player component for just one hour so new episodes should display quickly. It also means I can use non-https audio files, since I use the audio file referenced in the RSS; https is a requirement of AMP. This page component reads the RSS feed as well. The bespoke JavaScript sets a Chrome mediaSession, so Android devices will see a nice notification with an image, play data and even skip forward/back controls.

There’s a list of apps and icons below that. I wanted to produce a list that was device-aware, so I don’t list Apple Podcasts for an Android user, for example; but you can’t do that kind of dynamic content in AMP. After a little thinking, I hit upon the idea of using an amp-list component which reads a JSON file; that JSON file is dynamically generated using the user-agent (so I know if you’re using an Android, iOS or desktop device). This meant a bespoke ‘behaviour’ in Amazon Cloudfront, to allow that one component to get the user-agent header.

The results

I think I’ve achieved a very fast-loading page (in total it’s 260KB, and loads in under a second), which links out to the right apps for your device; a player which should work nicely even on mobile; and a simple, single place to link for podcasts on any platform.

The UX needs work: it’s still not as friendly as I’d like; and I’d like the ability to play the podcast to be more visible upon pageload (it’s frequently below the fold). But it’s a good start, and enables a consistent way to list and link-to podcasts, so that’s nice.