Almost EVERYONE who tried headless systems said they saw benefits. Download the state of CMS now!

Storyblok now on AWS Marketplace: Read more

O’Reilly Report: Decoupled Applications and Composable Web Architectures - Download Now

Empower your teams & get a 582% ROI: See Storyblok's CMS in action

Skip to main content

Build Your Own Link Hub With Storyblok, Astro and Edgio

Try Storyblok

Storyblok is the first headless CMS that works for developers & marketers alike.

  • Home
  • Tutorials
  • Build Your Own Link Hub With Storyblok, Astro and Edgio

This guide describes how to create and deploy your own Link Hub built with Storyblok & Astro to Edgio. Clone the repo link-hub-storyblok-astro-edgio-starter to get the entire setup.

Section titled Set up Storyblok space Set up Storyblok space

To set up a Storyblok space, log in to your account or create a new one, and click on New Space {1}.

create new space
1

create a new space

Create a new Storyblok space by giving it a name.

Select New Space, Give It A Name
1
2

Select New Space, Give It A Name and Click Create Space

Click on Create New {1} to get started with creating the Profiles folder.

create profiles folder
1

Create Profiles folder in your content space

Click on Folder {1} to get started with creating the Profiles folder.

Click Folder to start creating a collection of Profiles
1

Create a collection of Profiles

Imagine Storyblok's folder as a collection of items, and each Storyblok entry being an item itself. We'll be creating two folders: Profiles and Profile. Each entry that lives inside Profiles represents an individual Author or a Post.

After typing in the Name, click on Add New as the content type and give it a personalized Name (here: Link Hub Profile Links) as we'll be giving it our own blueprint. Click save to create a Profiles folder.

 Select the content type to “Add new” and give it a personalised name
1

Select the content type to “Add new” and give it a personalised name

start creating each profile
1

Click the Profiles folder to start creating each profile

Click on Create New to start creating your first Profile entry.

create your first profile
1

Click Create New to create your first profile

create your first profile
1

Select the personalized name of the content type you gave while creating the folder and create the first story

Click on Define {1} to start defining the Profile schema.

Define the profile schema
1

Click Define to set how a single profile data will look like

Add a Name field to the schema (type Text).

Adding a name field
1

After typing Name under the input, press enter to assign Name as Text type

Add an About field to the schema (type Text).

Adding an about field
1

Similarly, enter About as the Text Type

Add an Image field to the schema (type Asset).

Adding an image field
1
2

Now, type in Image that’d be associated with a user and click on icon near it. Change the item to being an asset.

For all the Links {1} that’ll be visible to the user, let's create a Blocks {2} so that we can insert as many associative links as we want to

Adding a links field
1
2

Adding a links field

For all the Socials {1} that’ll be visible to the user, let's also use a Blocks {2} field so that we can insert as many associative socials as we want to.

Adding social media profiles
1
2

Adding social media profiles

Add OG field to the schema (type Asset).

add OG field
1
2

Adding an OG image field

Click on the Settings Icon (Edit Field) {1} to change how the Image field is set up

Allowing external URLs in the Image field
1

Allowing external URLs in the Image field

Click on Allow external URL {1} and select Images {2} to limit the Asset type to images and also, allow linking to external URLs

Select allow external URL and change the file type of Images
1
2

Select allow external URL and change the file type of Images

Start adding links to the Blocks {1} field and choose the Feature block.

Adding links
1

Adding links

Click on the Feature {1} block created above and let’s change what each link can contain.

Click on the Feature button in the Links column
1

Click on the Feature button in the Links column

Click on Settings Icon (Edit Field) {1} to access the schema of the Feature block

Change how content in Feature is define by click on Edit Field
1

Change how content in Feature is define by click on Edit Field

Add an Image field to the schema (type Asset).

Create an Image type to associate with each link that’ll be present in the final view
1
2

Create an Image type to associate with each link that’ll be present in the final view

Add a URL field to the schema as the (type URL).

Create a field named URL of type URL where the link will point to when clicked
1
2

Create a field named URL of type URL where the link will point to when clicked

After clicking and save filling the information, this is how it looks once filled in

After clicking and save filling the information, this is how it looks once filled in

Similarly, create blocks for Socials
1

Similarly, create blocks for Socials

This is how the Socials feature will look once you’ve enabled all the fields created above

This is how the Socials feature will look once you’ve enabled all the fields created above

Next, obtain the Preview {1} API key (further referred to as STORYBLOK) shown in the tab Access Tokens of Settings. Obtain the token from the list as STORYBLOK.

Finally, with that done, obtain the preview token to be used in your code
1

Finally, with that done, obtain the preview token to be used in your code

Section titled Set up Astro with Edgio Set up Astro with Edgio

To set up, just clone the app repo and follow this tutorial to learn everything that's in it. To fork the project, run:


        
      git clone https://github.com/rishi-raj-jain/link-hub-storyblok-astro-edgio-starter
cd link-hub-storyblok-astro-edgio-starter
yarn install
    


After these steps, you should be able to start the local environment using the following command:

        
      yarn run edgio:dev
    

Section titled Implementing Data Fetching and Revalidation Implementing Data Fetching and Revalidation

In this section, we'll be diving deep into how the data fetching and revalidation for the user profiles is done. We make constant use of Stale While Revalidate on the Edge to achieve 100% cache hit rates, and @astro/storyblok to fetch and display data statically.

Section titled getUserInfo: Fetching the user profile getUserInfo: Fetching the user profile

The getUserInfo function uses Storyblok's useStoryblokApi hook to make an API request to the relevant user profile page, identified by a unique slug. If the story is present, the function extracts the name, image, about, links, social media profiles, and lastly SEO first open graph image from the returned data. The function maps the links and social media profiles to arrays and returns all the extracted data in an object with a code of 1.

Furthermore, If the story is not present or there is an error, the function returns an object with a code of 0 so that then the user can be redirected to 404 automatically.

        
      // File: lib/user.js

import { useStoryblokApi } from '@storyblok/astro'

export async function getUserInfo(slug) {
  try {
    const storyblokApi = useStoryblokApi()
    // Append cdn/stories/ before your full slug path
    const { data } = await storyblokApi.get(`cdn/stories/profiles/${slug}`)
    // If the story is there, return the required data
    if (data.story) {
      const { name, content } = data.story
      const { About, Image, Links, Socials, OG } = content
      return {
        name,
        image: Image.filename,
        about: About,
        links: Links.map((i) => [i.Name ?? i.name, i.URL.url, i.Image.filename]),
        socials: Socials.map((i) => [i.Name ?? i.name, i.URL.url]),
        og: { image: OG.filename },
        code: 1,
      }
    }
    return { code: 0 }
  } catch (e) {
    console.log(e.message || e.toString())
    return { code: 0 }
  }
}
    

Section titled Implementing stale-while-revalidate on the edge for all the user profiles Implementing stale-while-revalidate on the edge for all the user profiles

The following code describes how to use the concept of Stale While Revalidate to achieve 100% cache hit rates. In the code (in routes.js), the router.match function is used to match all the user profiles (that start with /me/). Inside the cache method, we prevent caching the page in browser and enable only edge caching to always serve users fast and with the latest content. The edge option is set to maxAgeSeconds: 1 to ensure that the data is cached for only a second. The staleWhileRevalidateSeconds option is set to be a year to allow the data to be served directly from the cache while the cache is being refreshed.

        
      // File: routes.js

// User path(s)
router.match('/me/:path', ({ cache, removeUpstreamResponseHeader }) => {
  // Remove the cache-control header from Astro's standalone server
  removeUpstreamResponseHeader('cache-control')
  // Disable in browser caching, and use Edgio's edge to use SWR
  cache({
    edge: {
      maxAgeSeconds: 1,
      staleWhileRevalidateSeconds: 60 * 60 * 24 * 365,
    },
    browser: false,
  })
})
    

Using Stale While Revalidate can help to improve the performance of the app by reducing the load on the server and providing faster responses to the user.

Section titled Creating dynamic user profiles on the fly Creating dynamic user profiles on the fly

Astro makes it super easy to set up dynamic routes. In the app, you'd find src/pages/me/[slug].astro, which maps pages that start with /me/. Examples include /me/user-1 and /me/some-new-user.

Section titled Fetching user profiles Fetching user profiles

We fetch the data for the current user by making use of the slug query parameter extracted out of Astro params, and call the getUserInfo function (as described above) to obtain all the related user data. In case of not found or an error, we redirect the visitor to a 404:

        
      // File: src/pages/me/[slug].astro

// Extract slug query
const { slug } = Astro.params

// Get data from Storyblok using the getUserInfo function
const {
  name: userName,
  image: userImage,
  links = [],
  socials = [],
  about = '',
  og = {},
  background = {},
  code = 1,
} = await getUserInfo(userSlug)

// In case the code: 0 is recevied, redirect to a 404
if (code === 0) {
  return Astro.redirect('/404')
}
    

Section titled Deploy from CLI Deploy from CLI

You can do a production build of your app and test it locally using:

        
      yarn run edgio:build && yarn run edgio:production
    

Deploying requires an account on Edgio. Sign up here for free. Once you have an account, you can deploy to Edgio by running the following command in the root folder of your project:

        
      yarn run edgio:deploy
    

Now we are done with the deployment! Yes, that was all. You should see something like this in the console:

Go ahead! Change content and publish it on Storyblok, and browse the /me/user-slug route of your website to look for changes (yes, revalidation works just like that!).

Section titled Summary Summary

In this tutorial, we learned how to build our own Link Hub with Storyblok CMS in a Astro project and deploy it to Edgio.


Author

Rishi Raj Jain

Rishi Raj Jain

Technical Customer Success Manager at Edgio. Storyblok Ambassador. Synchronising my knowledge with community about Web Development, Caching, Edge Computing, Serverless, front-end ecosystems.