Storyblok Raises $80M Series C - Read News

What’s the True Total Price of Enterprise CMS? Find out here.

Skip to main content

Creating global components and referencing them in Storyblok

Try Storyblok

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

In this tutorial, you will learn how to manage components such as banners, newsletter signup forms, or author profiles globally. Rather than having to manage these types of content per story, you can instead manage them from one central place, affecting multiple pages at once. Depending on whether you would like such referenced content on all pages or only on specific ones, you can either load them directly in your implementation or exert more granular control in Storyblok.

hint:

This tutorial assumes that you are already familiar with creating components, stories, and folders. Please refer to the Structures of Content developer guide to learn more.

Creating global components

The first step is to create a new content type component called global. In its schema configuration, we want to create a new Blocks field. Let's call this field global, too. Using a Blocks field offers maximum flexibility, allowing you to use whatever nestable component(s) you may need. In the advanced field settings, you may, however, want to limit the number and type of components that can be added.

Let's proceed by creating a new top-level folder called global in which all of our global components will be located. Furthermore, let's use the Restrict content types setting in the folder configuration to ensure that all stories created in this folder will be of the global content type.

Upon having created this folder, we can create our first entry there. Let's call it Newsletter Section, as this is a good example of a section we would like to implement on multiple pages but manage from one single place. Once the story is created, we can add any nestable component to the global Blocks field to store the content. Let's assume we already have a nestable component called newsletter_section with a headline, subheadline, and image field. Once you have added this component to the global field, you can add some example content to its fields.

Creating the reference component

Now that we have defined the structure for our global components, we can reference them. In order to do that, we can employ the References field.

hint:

The References field type is specifically designed to only allow referencing stories. This result in a more streamlined experience for content editors. Should you need further options, you can consider using the Single-Option or Multi-Options field types instead. You can learn more about the differences in our Structures of Content developer guide.

First, let's open the Block Library menu and click on the New Block button in the top right corner. Now, you can create a new nestable component with the technical name global_reference. Finally, let's add a new field of the type References and name it reference.

In the field configuration, we'll enter global/ in Path to folder of stories. This ensures that content editors can only reference stories that are located in the previously created Global folder. You may want to also utilize Restrict to content type, but as the folder already prohibits the creation of content types other than global, this setting is redundant in this particular scenario.

You can now use this global_reference in any field of the type Blocks, such as the body field of your home story. Now, however, all we will need to do there is select the entry that contains the component we want to display – in our case, this would be the Newsletter Section.

Using the global reference component and selecting the newsletter section

Using the global reference component and selecting the newsletter section

After pressing Save, you can check the API response by selecting Open Draft JSON from the list of entries in the dropdown menu next to the Publish button.

        
      {
  "story": {
    "name": "Home",
    "created_at": "2024-07-16T14:25:46.513Z",
    "published_at": null,
    "id": 523977987,
    "uuid": "8e754b74-de93-4c93-83d1-0355e5abfbb7",
    "content": {
      "_uid": "c7da28f5-c0b5-4c89-99b9-9395842e92a4",
      "body": [
        {
          "_uid": "066e1922-5f39-4148-a84a-70e1a1608b1f",
          "component": "global_reference",
          "reference": [
            "73922381-cf4c-437e-baaa-eb4649ad4b4a"
          ]
        }
      ],
      "component": "page"
    },
    "slug": "home",
    "full_slug": "home"
    ...
  },
  "cv": 1721140148,
  "rels": [
    
  ],
  "links": [
    
  ]
}
    

Resolving the relationship with the API

You will notice that we're only storing the UUID of referenced stories, and you will now be able to load that specific entry using its UUID. However, what we would like to achieve is to have that content included in the initial response, avoiding the need to load it with a second request altogether. Fortunately, the resolve_relations parameter of Storyblok's Content Delivery API lets us accomplish exactly that. This parameter is utilized by providing the component name, followed by the name of the field to be resolved, separated by a dot. In our particular case, this would result in resolve_relations=global_reference.reference.

Example request using the resolve_relations parameter
        
      https://api.storyblok.com/v2/cdn/stories/home?
    version=published&
    token={YOUR_ACESS_TOKEN}&
    cv=1721140148&
+   resolve_relations=global_reference.reference
    

Now, the API response will return the full story object of stories to be resolved and includes them in a rels array. This allows you to access all of the globally managed data and put it to good use.

        
      {
  "story": {
    "name": "Home",
    "created_at": "2024-07-16T14:25:46.513Z",
    "published_at": null,
    "id": 523977987,
    "uuid": "8e754b74-de93-4c93-83d1-0355e5abfbb7",
    "content": {
      "_uid": "c7da28f5-c0b5-4c89-99b9-9395842e92a4",
      "body": [
        {
          "_uid": "066e1922-5f39-4148-a84a-70e1a1608b1f",
          "component": "global_reference",
          "reference": [
            "73922381-cf4c-437e-baaa-eb4649ad4b4a"
          ]
        }
      ],
      "component": "page"
    },
    "slug": "home",
    "full_slug": "home"
    ...
  },
  "cv": 1721140148,
  "rels": [
    {
      "name": "Newsletter Section",
      "created_at": "2024-07-16T14:27:12.380Z",
      "published_at": "2024-07-16T14:27:27.891Z",
      "id": 523981786,
      "uuid": "73922381-cf4c-437e-baaa-eb4649ad4b4a",
      "content": {
        "_uid": "fab74f4c-7d78-4e3a-a1cf-af9986024814",
        "global": [
          {
            "_uid": "cfba34ed-3548-4c66-8a66-20e1c43915c0",
            "headline": "A simple newsletter section",
            "component": "teaser"
          }
        ],
        "component": "global"
      },
      "slug": "newsletter-section",
      "full_slug": "global/newsletter-section"
      ...
    }
  ],
  "links": []
}
    
hint:

For further information, please refer to our detailed developer tutorial on resolving relations.

Wrapping up

You can now create multiple global components and reference them in other stories. Importantly, using this approach for components or sections that exist on every page (such as a header or footer) is something we would not recommend. Instead, we would recommend loading them once, storing them, and reusing them from there. This approach of sending one additional request once rather than having such sections included in every API response is much more efficient.

Author

Manuel Schröder

Manuel Schröder

A former International Relations graduate, Manuel ultimately pursued a career in web development, working as a frontend engineer. His favorite technologies, other than Storyblok, include Vue, Astro, and Tailwind. These days, Manuel coordinates and oversees Storyblok's technical documentation, combining his technical expertise with his passion for writing and communication.