Build a headless blog with Astro and Optimizely SaaS CMS Part 4 - SSR & Visual Builder Experiences
For those new to the series, you may want to read parts one, two, and three first.
At the end of my last post I mentioned I had two more ideas to explore:
-
- Render some purely Visual Builder content
- Render the whole thing dynamically rather than statically.
Let's do that.
From Static to Server-Side Rendered (SSR)
I started a new server-side rendered version of the demo site that builds on everything added in the static site version. This means content changes in the CMS now appear on the SSR website version nearly instantly, without needing to trigger a new build on Vercel. For sites with lots of content changes, this will be a much more suitable approach compared to the webhook process we used with the static site version.
The core change was changing astro.config.mjs from static output to `output: 'server'`. This change tells Astro to stop pre-building all the pages into HTML files and instead render each page on the server when a user requests it.
I also had to install the appropriate Server Adapter, in this case `@astrojs/vercel` since this demo is running on Vercel.
This is great for content-heavy sites where updates are frequent, changes reflect as soon as they are indexed in Graph.
TypeScript
In the last post, I mentioned that the GraphQL integration could be improved by automatically creating TypeScript types. I thought given that I'm making more changes in the new version, I might as well add that too.
By installing the `@graphql-codegen/cli` package and setting up a codegen.ts config file, we can now run a single command: `npm run codegen`.
This command connects to our Optimizely Graph endpoint, scans our queries in apollo-client.ts, and automatically generates TypeScript types for them. When developing, this means:
-
Full type-safety: No more guessing what fields are available on a content item.
-
Intelligent autocompletion: The code editor knows our schema, which makes writing queries and using the data much faster and less error-prone.
I updated all the page and component layouts to use the imports from our generated types e.g.
import type { StartPage, ArticlePage as ArticlePageType } from '../gql/graphql';
It’s a nice improvement to the developer experience and something you’d want in any real-world project.
Adding Experiences and Visual Builder
The SSR version now properly supports Optimizely's Visual Builder with Experiences.
I've included three to get started:
-
ExperienceHero: A simple, reusable full-width hero banner with a background image and text overlay.
-
ExperienceCarousel: For creating responsive image grids.
-
ExperienceRTE: A standard Rich Text Editor for displaying any kind of formatted text content.
You can find them in the components folder in the repo, e.g. https://github.com/jacobpretorius/Opti.SaaS.Astro.Demo/blob/main/ssr/src/components/ExperienceHero.astro
Content editors can now compose these with Experience page type inside the CMS and see them rendered on page.
Visual builder has come a long way already.
Caching
Graph responses seem to be relatively quick, but as you might expect, a server-side rendered page that has to load page content from an external source for every request won't be as performant as a static site that can instantly start streaming the response HTML.
Thankfully, in-memory caching on the server is still possible. So I added a 2-minute cache for all normal page loads (non-preview mode). Only the first new Graph request will go out to Graph every 2 minutes. You can see and change the cache configuration to your needs in apollo-client.ts.
Conclusion
This new SSR version is a much more robust and dynamic foundation for building with Astro and Optimizely SaaS CMS. It brings the power of instant content updates and a true visual editing experience to the forefront, while making the development process more efficient with type generation.
It upgrades my example from a simple blog (like mine) into something you could use for a more complex and content-rich enterprise site.
Next time, I'll look at integrating the new beta Optimizely content-js-sdk.
Check out the live demo and the code for yourself
-
Live SSR Demo: https://opti-saas-astro-ssr-demo.vercel.app
-
Github Repo (SSR Folder): https://github.com/jacobpretorius/Opti.SaaS.Astro.Demo/tree/main/ssr
See you next time 😉
Comments