A JavaScript application can build its main content only after the browser receives the initial document. That creates a challenge for link-preview services and crawlers with limited JavaScript support. The prerender service I built supplied a rendered HTML version of the existing page to those requests.
The engineering problem extended beyond opening a page in a browser and saving the result. Request routing, retention of the generated HTML and refresh behavior all affected whether the product could provide a useful representation of the source page.
Routing the request before the application
The customer's web server decides whether a request needs the rendered version. An eligible crawler is routed to the prerender service, while a human visitor continues through the application's normal delivery path. Static assets such as scripts, images and stylesheets should avoid unnecessary rendering work.
Keeping that decision at the web server allowed integration without rewriting every application page. The HTML returned to a crawler still needs to represent the content a visitor would see at the same address. Serving a different product or different information to bots is outside that purpose.
Using Redis as the primary read path
Rendering a page in a browser costs more than reading already generated HTML. Crawlers also revisit the same addresses, so processing each request from scratch creates repeated work. I stored rendered pages in Redis and served later requests from those records.
In this design, the cache is central to the product's delivery path. A missing page, an available rendered copy and a copy awaiting refresh are different operating states. Finding a cached record does not establish that its content is still current.
Choosing refresh behavior for the content
A news page and an infrequently changed company page do not need the same refresh interval. Rendering more often can improve freshness, but also increases browser work and the load placed on the source site. I exposed the refresh interval as a product setting that reflects this tradeoff.
The management interface used Laravel and Tailwind CSS. Project owners could inspect cached addresses and manage refresh settings there. The generated version therefore remained an operational part of the product rather than an invisible copy that could be forgotten after integration.
Checking the HTML beyond its appearance
The rendered title, description and canonical address need to remain consistent with the original page. A cached redirect or incorrect status response can introduce a different SEO problem even when the visible text is present. A screenshot is useful, but it does not establish that those delivery details are correct.
Comparing the visitor and crawler representations at the same address reveals differences in content, links and metadata. Language variants also need independent attention: one locale's cached HTML should not be returned under another locale's address.
Choosing a rendering model for new work
Google's dynamic-rendering guidance treats this approach as a workaround and recommends server rendering, static rendering or hydration instead. That distinction matters when choosing the initial architecture of a new product.
Prerendering can address a specific need in an existing application, while introducing an additional delivery path that must stay current and consistent. The product decision should account for when content is generated, how it changes and how visitors beyond search crawlers receive it.