Home App Docs Github

Cacheable server(less)-side rendering

Just started getting my feet wet with Builder.io and it’s pretty awesome. I’m looking at using it for an ecommerce frontend with a kind of shocking number of products that makes our it incompatible with most popular off-the-shelf ecommerce platforms, and this seems like a fantastic way to add a frontend to a bespoke product and cart backend.

My question is this: We’re using Lambda@Edge to prerender pages, which gives us the option of caching the render so it’s served directly from Cloudfront the next time this exact page is requested. This is necessary to keep our lambda and request costs reasonable. However, while 99% of each page is safe to cache and serve up to any future user, the little div that shows the logged in user obviously isn’t.

What’s the best practice for blocking an element from prerender so that React can hydrate it and render client-side? I’d really love for my marketing team to have access to the full page design from within Builder, but am looking at hacky solutions around this that don’t feel clean yet.

Thanks!

Hey Tom,

Thanks so much for reaching out. It sounds like you have a really interesting project! In order to point you in the right direction, I have a quick clarifying question – Are you looking to use Builder components that are only rendered client side, or are you creating a custom component for use within Builder that you would only like to have rendered on the client?

Gosh, I guess I’d be interested to hear the best practices for both. I have two thoughts running through my head right now:

  1. I’d love to build a library of custom components, register them with builder.io, and then Builder becomes our entire website. In this scenario, the username/login/logout component would be “within” builder so we can use it in the design but the SSR API would have to omit it and force React to hydrate it and render client-side. Alternatively we could use Builder’s built-in actions and state management for this too – end result is the same.

  2. The store could have upwards of 15 million products in it, and if each of those pages loads just once per day that’s 1 million requests to the lambda AND 1 million requests to Builder.io which makes costs scary. If there’s a way to have Builder’s SSR API return the components for a product page generically, and then have React attach to that to render the actual data for the product? So in essence, Builder.io would know about “/product” and have one single generic product with an image selector component and a placeholder description and reviews, then when a request comes through for /product/product-name-1, we render the /product page from builder, hydrate it with React, and replace the generic content?

I think the easiest approach here would be to add logic that only fetches product data when the app detects it is running in the browser. You can add the fetch data within the content entry in Builder under the custom JS section, or just bake it into your custom component logic if you go that route. In either case this check can be done using Builder.isBrowser . Here is an example piece of code:

if (Builder.isBrowser) {
fetch(<someurl>).then(res => res.json()).then(product => state.product = product);
}

You can also take this approach to have some generic product data load in from your API to populate data then someone is using the Builder editor (there is also the property Builder.isEditing if you would like to use that within your fetch call to your API).

For more info on fetching data based on URL with custom JS, check out this guide: https://www.builder.io/c/docs/guides/advanced-data

As far as building out custom components go, have a look at our guide for using your own react components within builder: https://www.builder.io/c/docs/custom-react-components.

Hope that helps!

Those booleans are wildly helpful, thank you!!