Conversation
The service worker's precache list was templated per-user from the `docs` cookie, so every /service-worker.js response varied by request and the server had to read the cookie to render it. This removes that dependency: the install list is now just the stable app shell, and the fetch handler caches documentation index.json files at runtime as they are requested, so enabled docs stay available offline without baking the per-user list into the file. This also makes the install more robust — cache.addAll is atomic, so a momentarily-unavailable doc index can no longer fail the whole service worker install. With this, the server reads no cookies at all: drop the now-unused docs, user_has_docs?, doc_index_urls and memoized_cookies helpers along with the sinatra/cookies dependency. The enabled-docs list remains a client-side cookie (via CookiesStore) and could later move to localStorage since nothing server-side depends on it.
Add docs/storage.md describing the four storage layers (enabled-docs list, per-doc index, doc content, service worker cache), where each lives, and when it is written.
Single-doc mode (viewing one documentation in a focused, IndexedDB-off view) was triggered by the server rendering other.erb with the doc's metadata inlined as a data-doc body attribute. That required a distinct per-doc server-rendered shell. Detect it on the client instead: doc pages now render the normal app shell (index.erb, which loads the full catalog), and on boot the app inspects location.pathname — if the first segment resolves to a doc in app.DOCS, it boots single-doc mode for that doc; otherwise it boots the full app, which continues to resolve aliases, redirects and 404s. The ~33 KB catalog is loaded either way, which is an accepted tradeoff. isSingleDoc() now reads an internal flag set from the URL rather than the data-doc attribute; the flag is computed at the very top of init() so error-tracking's mode tag stays accurate. Drops other.erb, the data-doc plumbing and the now-unused doc_index_page? helper.
Upstream 669abd4 moved index.json to load from docs_origin (the documents.devdocs.io CDN, a different origin in production). Update the per-doc index and service worker sections to match.
Add an assets:render_static step that renders the app shell, the service worker and the news feed to static files under public/, so the app can be served without the Ruby process. Rendering goes through the real Rack app (App.call) so the output is byte-identical to what Sinatra serves. It runs after compile in the assets:precompile pipeline and re-points the asset helpers at the freshly compiled manifest first, since the app booted before the manifest was written. The generated files are gitignored.
Serve the prerendered public/ output (index.html, service-worker.js, feed.atom and the compiled assets) with no Ruby at request time. The config mirrors the request-time behaviour of lib/app.rb: the security and per-path cache headers, the full redirect table (sponsor links, legacy paths, DOC_REDIRECTS renames, angular/dom fragment rewrites, /maxcdn 410, /search and /?q= to the hash query), doc-slug trailing-slash canonicalization, the /feed Atom endpoint, the out.devdocs.io tracking domain, and an index.html SPA fallback for everything else. Additive only — config.ru and the Sinatra app are unchanged; this is an alternative front end. Validated with caddy v2 and smoke-tested against public/. Each rule is commented with the app.rb construct it mirrors.
This was referenced Jul 15, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
No description provided.