dgp1130 / rules_prerender

A Bazel rule set for prerending HTML pages.
13 stars 0 forks source link

Serve multiple routes from the same generated HTML #52

Open dgp1130 opened 1 year ago

dgp1130 commented 1 year ago

Consider the use case of a product catalog. You likely want users to visit /product/1234.html to view the product. The only real way to accomplish this with rules_prerender today is to iterate over all product IDs and generate distinct pages:

export default function*(): Generator<PrerenderResource, void, void> {
  for (const productId of productIds) {
    yield PrerenderResource.of(`/product/${productId}.html`, renderProduct());
  }
}

This has two key problems:

  1. It requires build-time knowledge of all product IDs. This may not feasible or even useful if product specific data is loaded and rendered on the client.
  2. It duplicates most of the rendering work per-page unnecessarily. If all product pages are identical with only CSR differentiating them, then there's no value in duplicating the generated content.

It would be great to configure routes, so that the same product page could be served at multiple URLs. This is even more useful if SSR is implemented, since these pages could dynamically SSR different content based on the request URL, without duplicating the SSG content.

This feature fundamentally requires a server with knowledge of these routes and can't be a static HTTP file server. If we do implement SSG which requires a generated server anyways, then this becomes a very compelling feature. If we can define some syntax which indicates that /product/[^/]* should actually serve the SSG'd /product.html page, it would satisfy this use case. SSR/CSR could fill in any remaining content with knowledge of the request URL, while SSG doesn't need to know all the products or duplicate it's effort per-product.