
How to repurpose a very old iPad into a scrolling news display. You will need: a very old iPad, some web space to run the code, and (if you’re like me) an Ai coding assistant to write and debug the code for you.
I had an old iPad (an A1416, from 2012) which I didn’t want to throw away. Surely I could put it on the wall and do something decorative or even useful? But it hardly seemed able to do anything. Even running it as a photo frame seemed to produce spinning wheels, probably due to the size of the modern iCloud photo library I was attempting to make it access. Useless, right? I was determined to prove otherwise.
Playing around with the apps left on it, I came across an old RSS news reader which had a “slideshow” function. This looked cool: a scrolling news headlines display. Now that I could use. And it worked! The problem was, the news feed never refreshed. It just scrolled through the same headlines forever. So… nice idea, but we’d need a different implementation.
I wondered if I could do something similar in Safari. It turned out that I could. It needed some web space, and some knowledge of JavaScript, PHP and web page design. Until the last year, that would have been beyond my mediocre coding skills. Now, however, I could turn to ChatGPT to handle all that.
Here’s how “we” (ChatGPT and I) did it, and the problems we overcame. It might seem like a chore, but it was surprisingly quick and easy. I won’t post the finished code here, as I think every implementation will be different. However, at the end there’s a ChatGPT prompt that might help you put your own solution together.
What we were trying to build
The aim was to create a web page that pulls an RSS feed and shows one item at a time, like a slideshow. The kind of thing we can leave running on an old iPad in the corner of an office, quietly cycling through headlines.
Our very first attempt behaved perfectly. It fetched the feed, rotated through items, refreshed periodically. Job done.
But that was the development version on a modern MacBook…
Then we pointed the older iPad at it, running iOS 9.3.5, the most recent it was ever going to be allowed to run. Safari looked at our page, displayed the word “Loading…”, and seemingly decided that was a nice happy place where it could spend the rest of its natural life.
The first surprise: failure without drama
That was the moment the project stopped being about a slideshow and became about the reality of building small web utilities for older kit. The code can be tidy. The idea can be straightforward. The environment can still set traps.
The first trap was the browser itself. When a script fails early, Safari does not always make a fuss. On the old iPad it often fails silently. No helpful error messages on screen. No clear clues. Just the same frozen first frame.
So we leaned on a basic debugging pattern. Add one tiny line of JavaScript in the page itself, before anything else loads, and make it change the title. If that line runs, JavaScript is alive. If it does not, you are chasing the wrong problem.
Debugging by finding the dropped baton
That told us JavaScript was running. The next question was whether our external script file was being loaded and executed. Another small marker after the script tag helped there. We started treating the page like a relay race. Baton passed to inline JS. Then passed to external JS. Find the handoff where it drops.
Once we knew where it dropped, the next trap revealed itself: caching.
Caching is usually helpful. But on an old iPad, with a hosting setup that may include intermediate caching layers, it can turn into quicksand. We changed the page, refreshed, and the iPad kept serving the old copy like it was doing us a favour.
When caching stops being helpful
Clearing Safari data and quitting the app helped sometimes. At other times it did nothing. The only reliable solution was blunt and boring: change the filenames. Not just a query string at the end, but a genuinely new file path. A new name is a new object in every cache, whether it is the browser, the CDN, or something in between.
That became our deployment ritual. We stopped overwriting files in place. Instead, we published versioned filenames, like:
slideshow-20260303-1000b.js
slideshow-20260303-1000b.css
Then the main page pointed at the new names. When we wanted to change the styling, we published a new CSS filename, updated one build string, and moved on. It felt a bit old-school. It also worked every time.
Making the page itself harder to cache
We took the same approach for the HTML itself. Safari can be stubborn about caching the page shell too, so we served the main page via a small PHP wrapper that sends “do not cache” headers. The page becomes a little less static, but far more predictable. In kiosk projects, predictable wins.
That wrapper also helped with another early problem: browser security rules that make it awkward to fetch an RSS feed directly from a web page. Pulling the feed server-side and handing it to the page avoids those restrictions and makes the whole thing more reliable.
The feed is not a clean spec
And then came the third trap: the feed.
RSS feeds are simple in theory. In practice, they are whatever the publisher happens to output. Most items had a description. Some did not. Some titles were plain text. One or two titles contained HTML links inside the title field, which is a bit like finding a fork in your soup.
That kind of thing is harmless until you display it in a way that interprets HTML. If your code drops the title into the page as HTML, the browser will treat that embedded link as a real link. Safari will then apply default link styling. Suddenly your carefully designed white headline becomes a bright blue underlined link. Not a great look on a big display.
A simple rule that prevented ugly surprises
The fix was more about discipline than cleverness. Titles should be treated as text, not HTML. We changed the code to insert the title using a method that never interprets markup. And just in case anything slipped through, we added defensive CSS so even a rogue link in a headline would still look like a headline.
We also added a small fallback for missing descriptions. If an item had no <description>, we either displayed nothing (cleaner than a broken layout) or looked for an alternative field (some feeds put the summary elsewhere). The main goal was: never let one odd item break the whole display.
This is the kind of thing I keep relearning in marketing tech and web work. The real world is not a clean spec. It is a bunch of “usually” statements, plus a few awkward exceptions that only appear once you deploy.
Turning Safari into something app-like
Finally, we designed the iPad experience to feel like an app. Safari has its own furniture: address bar, buttons, the usual clutter. We cannot reliably remove that when running as a normal web page. But iOS does give us a decent compromise. Add the page to the Home Screen as a “web app” and it runs without the browser chrome.
Pair that with Guided Access and the iPad becomes much harder to accidentally break out of. For a single-purpose screen that runs 24/7, that matters.
What we actually learned
In the end, the slideshow worked. It refreshed. It looked clean. It survived the old iPad. It even handled the feed’s odd little quirks.
But the bigger takeaway is that the hardest problems were not technical in the sense people usually mean. They were practical. CORS rules that make sense until you are trying to read a feed. Caching that helps until you need a stubborn device to accept an update. Content that is mostly consistent until one item is not.
That is what building small, useful tools is often like. The idea is simple. The reality is a list of edge cases. And the win is learning which ones to solve with elegance and which ones to solve with a new filename and a shrug.
Improvements?
Using a single themed RSS feed from a news organisation is fine, but I think I’ll try next to roll my own feed from several sources, to create a news ticker that’s genuinely personalised…
Other Setup Steps
- Disable Auto-Lock: Navigate to Settings > Display & Brightness and set Auto-Lock to Never to keep the news visible at all times.
- Enable Guided Access: Found in Settings > Accessibility, this feature locks the iPad into a single app, preventing others from accidentally closing your news display.
- Power Management: To prevent battery swelling from being plugged in 24/7, some folks suggest using a smart outlet to cycle the power off for a few hours each day.
- Mounting: Attach to walls using Command Strips for a clean, non-permanent look.
Prompt: generate your own RSS slideshow “app”
Copy/paste this prompt into ChatGPT (and edit the bracketed bits).
Act as a pragmatic web developer helping me build a simple RSS slideshow that runs reliably on an old iPad (iOS 9.3.5) in Safari, and can be left running 24/7.
My hosting is plain shared hosting with PHP. I want a web page that:
- Fetches a specific RSS feed (URL: [PASTE RSS URL])
- Displays one item at a time: headline (very large), excerpt (half the size), and pubDate at the bottom
- Auto-advances every [15] seconds
- Refreshes the feed every [10] minutes
- Shows “Last refreshed at HH:MM:SS” at the bottom
- Uses a very dark grey background, white headline, light grey excerpt
Important constraints and fixes (must be implemented):
- CORS: Browsers may block direct RSS fetches. Provide a small PHP proxy (rss-proxy.php) that fetches the feed server-side and returns XML.
- Caching: iOS 9 Safari and CDNs can aggressively cache HTML/JS/CSS and ignore query-string cache busting. Use versioned filenames for JS and CSS (e.g. slideshow-YYYYMMDD-HHMM.js and .css) and a slideshow.php wrapper that sends no-cache headers.
- Old Safari compatibility: Write ES5 JavaScript only (no const/let, arrow functions, template literals, fetch, Promise, Set, Array.from, optional chaining).
- Rogue feed items: Some items may have <description/> empty and some feeds may embed HTML inside <title> (e.g. an <a> tag). Ensure the title is inserted as plain text (not innerHTML), strip any tags, and add defensive CSS so any accidental link inside h1 is not blue/underlined.
- If description is empty, display an empty excerpt area cleanly (no broken styling). Optionally fall back to media:description if present.
Deliverables:
- slideshow.php (the main page) including iOS “Add to Home Screen” meta tags (apple-mobile-web-app-capable etc.)
- slideshow-YYYYMMDD-HHMM.css
slideshow-YYYYMMDD-HHMM.js - rss-proxy.php (locked to the single feed URL, includes modest server-side caching if you think it’s appropriate, but sends no-store to clients)
Provide the full contents of each file and a short install checklist (what to upload, and what URL to open).