Taps can be unreliable inside this app's built-in browser. For the full experience, use its menu to open this page in your browser.
Skip to content

One URL, Two Different Files

A devlog by Neeraj Kotwani, who builds every game on Elipar.

Every game here is a small self-contained web page that runs inside a frame on a proper Elipar page, with the title, the description, the leaderboard and so on around it. Because that bare file can in principle be opened on its own, it carries a little banner saying "you're viewing this outside Elipar" with a link back.

A player started seeing that banner. Not by hunting for the raw file: by tapping a game on the homepage. Sometimes. Then a link shared over WhatsApp did it too. Then the installed app on Windows. Then Safari on an iPhone.

A week on the wrong thing

"Intermittent, several devices, worse in installed apps" is a caching bug. I've read that sentence in enough bug reports to be confident about it, and this site has a service worker that caches game files aggressively so they work offline.

So I went through the caching. And I did find three real bugs, all worth fixing, none of them the cause:

The service worker script itself had no cache header, which is quietly circular. I'd been bumping the cache version inside the file to invalidate old caches, but the file was being served from the edge cache, so the browser fetched identical bytes every time, never noticed a change, and never activated a new worker. Every version bump I'd made for weeks had done nothing.

The update check only ran when the tab regained focus, which an installed app window may go days without doing.

And my interim fix introduced a fourth: the banner's redirect had no guard against the target being the page it was already on, so under the right conditions it redirected to itself forever. The player described this as "blinking all screen", which is the single most accurate bug description I have ever received.

What it actually was

The player sent me screenshots from a fresh incognito window. Incognito means no service worker, no site data, nothing cached client-side. And the exact URL /games/pro-football-3d was serving the raw game file.

That killed every theory I had at once, which was a relief.

The cause is embarrassingly simple in hindsight. That URL was two things. It was a page route in the app, and it was also the folder holding the game's static files, at the same prefix. Both real, both valid, sitting on the same address. Most of the time the page won. Occasionally, on a full navigation, the edge served the file instead.

And it was not reproducible on my machine, ever, because running the site locally doesn't involve the edge at all. All that local testing coming back clean wasn't bad testing, it was testing a layer where the bug cannot exist.

Move it rather than argue with it

I could have tried to tune which one wins. Instead the game files moved to a different path entirely, so the page routes and the static files now live under prefixes that can never overlap. 472 file renames, and the ambiguity is gone by construction rather than by configuration.

Two details from that move.

The old URLs still need to work, so there's a redirect from the old file paths to the new ones. It matches one or more extra path segments, not zero or more. Zero-or-more would also match the bare page route, which is precisely the collision I was removing. One character of difference between the fix and recreating the bug.

And updating the catalogue file: my first attempt used a JSON library to rewrite it, which escaped every non-ASCII character in the whole file into \u sequences. I caught it because the diff was around 574 changed lines when I expected about 52. I now check the size of a diff against what I expected before committing a scripted edit, because that number is free and it's caught two things since.

The part I didn't see coming

Weeks later a player mentioned that a link shared to Facebook showed a blank image where the preview should be.

That redirect. It matches a game slug plus one or more segments. And the framework generates its social preview images at exactly that shape, /games/<slug>/opengraph-image, which is not a file on disk at all. So every preview image request was being redirected into the static folder, where no such file exists, and 404ing.

All 47 games. Every link anyone shared to Facebook, WhatsApp, Twitter, Discord or iMessage had a broken image, for weeks.

Nothing in my own checks could have caught it. The page returns 200. The tag is present and correct. Nothing throws. A broken preview only exists in somebody else's chat app. The redirect now requires the remaining path to contain a dot, so it matches real files and not generated routes, and there's a check that fetches every preview image on every route and asserts it comes back as an actual image over a few kilobytes.

If you add a redirect on a path prefix, go and enumerate everything else that answers under that prefix. Your framework's generated routes will not show up in a directory listing, because they aren't there.

Pro Football 3D and the other 46 games are all one tap from the homepage, and they land on the right page now.

We use cookies to keep games running and, once ads are live, to show relevant content. See our Privacy Policy for details.