Astro-Storyblok Previews Site with Netlify's Branch Deploys Feature

sandrarodgers

SandraRodgers

Posted on March 20, 2023

Astro-Storyblok Previews Site with Netlify's Branch Deploys Feature

Description: This article will tell you how to set up your Astro-Storyblok projects so that your previews site deploys to a Netlify branch-deploy, while keeping your main production site in SSG mode. Bonus: Github action to keep preview branch in-sync with production.

Introduction

If you are using Storyblok as your headless CMS for a static site such as a blog, you might want to set up a workflow where editors can click 'save' in Storyblok, and then see their changes. This would mean setting up the visual editor to work in Storyblok, which as I explained in a previous article, requires your Astro project to be in SSR mode.

What if you want to take advantage of Astro's static website mode (SSG) for your production site, but you would still like previews to work in Storyblok? How can we do this if previews require the project to be in SSR mode?

If you are using Netlify for deployments, there is a way to create an Astro project that builds the site in SSG mode for production environments and SSR mode for a previews branch , then deploys each version to a different Netlify URL using the Netlify branch-deploy feature.

You can also set up a Github action to keep the preview branch always up-to-date with any changes deployed to your main (production) branch!

Here's a walkthrough for how to set this up.

1. Create a branch-deploy in Netlify so you can have a special branch just for previewing content when clicking the 'save' button in Storyblok

Resource: Netlify Branches and deploys

Create Previews Branch

In your project, create a branch off of main called previews.

Go into your Netlify dashboard Deploys -> Deploy Settings -> Branches and deploy contexts.

  • Click Edit Settings.
  • Select 'Let me add individual branches'
  • In the Additional branches input, add your branch that you created called previews.

Now you have a branch that you will use for your preview environment. You're going to set up your Astro project to build in SSR mode just on this preview branch.

By the way, in Netlify terminology, a branch that you create which corresponds to a deploy that isn't from the main production branch is called a branch-deploy. There are different Netlify deploy-contexts, and branch-deploy is one of them (in addition to production and deploy-previews.

Create Environment Variables

You need to make sure that you have an environment variable that tells Netlify that this branch you created is the preview environment. Later, when you go into your Astro project, you'll set up the project to build differently based on these variables.

In Netlify, go to Deploys -> Deploy Settings -> Environment variables.

  • Create an environment variable called VITE_ENVIRONMENT.
  • In the Branch deploys, create a variable with the value preview. (Of course you can name this variable differently if you prefer.)

Now Netlify can be told based on the VITE_ENVIRONMENT variable to either build the branch in SSG mode for production, or build it in SSR mode for the previews branch.

2. In the Storyblok Visual Editor settings, add your Netlify preview branch URL to the Preview URLs

Log in to your Storyblok space. In the left side navigation menu, find settings. From there, navigate to Visual Editor.

This is where you will tell Storyblok to connect the Visual Editor to that special branch you created, the previews branch-deploy.

In the section Preview URLs, there are inputs to add multiple preview domains. Add previews where it asks for Name and the Netlify url for that deployed previews branch where it asks for Location.

You can look at the Netlify URL to know which deploy-context (i.e. which branch-deploy) the preview site is building from. Since you called your branch-deploy previews in Netlify, you'll see something like https://previews--NETLIFY_URL. If you were looking at a Netlify deploy-preview, it would look like https://deploy-preview-32--NETLIFY_URL (where the number is the number of the deploy-preview).

3. Set up your astro.config.mjs file so that it uses conditional logic to build your site in static mode if its in production, server mode in the preview environment

Now you'll head into your Astro project to add some necessary configuration. This is where the environment variable you set up in Netlify is going to come into play.

Set up .env

In Netlify, you created the environment variable VITE_ENVIRONMENT with the deploy-context of Branch deploys being given the preview value.

In your project, you'll need to create a .env file to supply your project with that variable value so it can work in dev mode. In the .env file, add VITE_ENVIRONMENT="preview".

Add configuration to astro.config.mjs

There are four properties in the config object given to defineConfig that will need to be written as ternary conditionals. They are output, accessToken (in the Storyblok settings object), and bridge (also in Storyblok settings), and adapter.

For output, you'll give a value that is dependent on whether the deploy-context is preview or not. Here's how it would look:

output:  import.meta.env.VITE_ENVIRONMENT  ===  "preview"  ?  "server"  :  "static",
Enter fullscreen mode Exit fullscreen mode

This will tell the project to build in server mode (i.e. SSR) if it's deploying to the preview branch. If it's not, it will build in static mode (SSG).

The integrations array in the configuration object contains a storyblok method with a settings object passed in. You'll need to add ternaries for the accessToken and bridge like so:

storyblok({
    accessToken:
        import.meta.env.VITE_ENVIRONMENT  ===  "preview"
        ?  "HodE5R9wdAKERDFNiq7LGStl" : "UUtz6RYjUvOC0tMf1MteHQtz",
    bridge:  import.meta.env.VITE_ENVIRONMENT  ===  "preview"  ? true :  false,
    apiOptions: {
        region:  "us",
    },
    components: {
        page:  "storyblok/Page",
        feature:  "storyblok/Feature",
        grid:  "storyblok/Grid",            
        ...
        },
    }),
Enter fullscreen mode Exit fullscreen mode

This tells the Storyblok integration to use the Preview token if the site is deploying in SSR, and the Public token if the site is deploying in SSG. (These Storyblok access tokens are created in your Storyblok space in Settings > Access Tokens.)

In the article I previously referenced, which is where I show how to set up the Visual Editor, I discuss how to add the Netlify adapter. The Netlify adapter is needed for the SSR deploy-context. You can read that article for more information if you need it on setting up SSR. You will need to set up the Netlify adapter.

You can tell your project to use the Netlify adapter only in SSR mode:

adapter: import.meta.env.VITE_ENVIRONMENT === 'preview' ? netlify() : undefined,
Enter fullscreen mode Exit fullscreen mode

Here's an example of how the astro.config.mjs file might look. There might be differences depending on your project integrations, but this is a general example:

import { defineConfig } from  "astro/config";
import  storyblok  from  "@storyblok/astro";
import  netlify  from  "@astrojs/netlify/functions";
import  tailwind  from  "@astrojs/tailwind";

export  default  defineConfig({
    output:  import.meta.env.VITE_ENVIRONMENT  ===  "preview"  ?  "server"  :  "static",
    adapter: import.meta.env.VITE_ENVIRONMENT === 'preview' ? netlify() : undefined,
    integrations: [
        tailwind(),
        storyblok({
            accessToken:
                import.meta.env.VITE_ENVIRONMENT  ===  "preview" ?  "HodE5R9wdAKERDFNiq7LGStl" : "UUtz6RYjUvOC0tMf1MteHQtz",
                bridge:  import.meta.env.VITE_ENVIRONMENT  ===  "preview" ? true :  false,
                apiOptions: {
                region:  "us",
                },
                components: {
                    page:  "storyblok/Page",
                    feature:  "storyblok/Feature",
                    grid:  "storyblok/Grid",
                },
            }),
        ],
});
Enter fullscreen mode Exit fullscreen mode

4. Get page data from Storyblok using the public token in SSG mode, the preview token in SSR mode.

The Astro pages that pull in content data from Storyblok can pull in either draft content or published content. You need to tell your project to build the pages using draft content when in the preview deploy-context, and published content when in production.

For every page in your Astro pages folder, you will do something like this when getting data from the Storyblok API:

const { data } =  await  sbApi.get("cdn/stories/home", {
    version:
        import.meta.env.VITE_ENVIRONMENT  ===  "preview"  ?  "draft"  : "published",
});
Enter fullscreen mode Exit fullscreen mode

This will conditionally build the project using either draft or published content based on that environment variable value in Netlify.

Here is an example of a home page in an Astro project that does this:

---

import { useStoryblokApi } from  "@storyblok/astro";
import  StoryblokComponent  from  "@storyblok/astro/StoryblokComponent.astro";
import  Layout  from  "../layouts/Layout.astro";

const  sbApi  =  useStoryblokApi();
const { data } =  await  sbApi.get("cdn/stories/home", {
    version:
        import.meta.env.VITE_ENVIRONMENT  ===  "preview"  ?  "draft"  : "published",
});
const  story  =  data.story;
---

<Layout>
<StoryblokComponent  blok={story.content} />
</Layout>
Enter fullscreen mode Exit fullscreen mode

For creating dynamic routes, you can use a conditional setup to tell your project to use Astro's getStaticPaths method in SSR mode only. Checkout this Discord comment for an example by user Nikitos.

5. Create a Github action that automatically merges any changes made to main to the previews branch too

The last thing you might want to do is to set up a continuous integration so that your preview branch stays in-sync with the main branch. That way, when there is a deploy to production, you don't have to manually update the previews branch - it will happen automatically.

You can use a Github Action to do this. Here's what you need to do.

  • Create a .github folder in your project at the root. Inside that folder, add a workflows folder.
  • Create a file called auto-merge.yml inside the workflows folder

github folder structure with workflows and auto-merge.yaml file

  • Add the following code to that file:
name: Merge main to previews
on:
    pull_request:
        branches: [main]
        types: [closed]
jobs:
    merge-main-to-previews:
    if: github.event.pull_request.merged == true
    timeout-minutes: 2
    runs-on: ubuntu-latest
    steps:
        - uses: actions/checkout@v3
        - name: Set Git config
        run: |
            git config --local user.email "actions@github.com"
            git config --local user.name "Github Actions"
        - name: Merge main to previews
        run: |
            git fetch --unshallow
            git checkout previews
            git pull
            git merge --no-ff main -m "Auto-merge main to previews"
            git push
Enter fullscreen mode Exit fullscreen mode

Now, anytime a pull request is merged to the main (production) branch, it will also merge those changes into the previews branch!

💖 💪 🙅 🚩
sandrarodgers
SandraRodgers

Posted on March 20, 2023

Join Our Newsletter. No Spam, Only the good stuff.

Sign up to receive the latest update from our blog.

Related