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

Rendering the Link field

If you want to create a link in your component, for example, a button component {1} with a label and a link (a call to action), you can use Text as the field type for the label and Link as a field type for the URL.

Building a Call to Action with Storyblok
1

Building a "Call to Action" button with a label and a destination URL.

If you need to understand how to create a link field in the Storyblok UI, you can read the article Component/Schema Configuration. In the current article, instead, we will approach the topic of links from a more technical point of view to see how information is handled at the API response level.

Depending on the configuration of the Link field, when content editors change the value of the link, they can select one of these link types:

  • URL: provide an external URL, path, or anchor
  • Asset: select an asset from the internal Digital Asset Management system
  • Email: provide a valid email address (Storyblok will perform syntax validation for the email address in this case)
  • Internal Link: select a story or a folder

When developers retrieve the story via API, an object of type link is obtained from stories that include a Link field type.

This is an example of a link object with an external URL:

"cta": {
  "id": "",
  "url": "https://www.storyblok.com/",
  "target": "_blank",
  "linktype": "url",
  "fieldtype": "multilink",
  "cached_url": "https://www.storyblok.com/"
},

One of the attributes of the link object is the linktype, which may have a specific value depending on the type of link selected by the content editor. Possible values are asset, url, story, and email. Therefore, to correctly utilize the information in the link object to generate a valid URL, a specific logic must be applied depending on the value of the linktype field.

In the previous JSON example, because the linktype is set to url, the relevant attributes are the url attribute that contains the full URL, and the optional target attribute that could be used, for example, to open the link in a new browser tab or browser window.

Now that we have a general overview of how links are handled in Storyblok let us look in detail at the various types of links available.

If you need to create an external link, like, for example, a link to https://storyblok.com, you can use the URL link type. In this case, the linktype field is set to url and you can find the full URL in url field.

If you want to create an internal link to a named anchor, you can also use the URL link type. An example is:

"cta": {
  "id": "",
  "url": "#some",
  "linktype": "url",
  "fieldtype": "multilink",
  "cached_url": "#some"
},

In the case of the anchor URL, the linktype field is set to url and the url field is the anchor's name, for example, #some.

In the case you want to create an external link with the anchor you can do it via he URL link type, and in this case the example is:

"cta": {
  "id": "",
  "url": "https://www.storyblok.com/docs#api-documentations",
  "linktype": "url",
  "fieldtype": "multilink",
  "cached_url": "https://www.storyblok.com/docs#api-documentations"
},

In the case of the anchor URL, the linktype field is still set to url and the url field is the full URLs with the anchor's name, for example, https://www.storyblok.com/docs#api-documentations.

If you need to create a link to an asset, like, for example, a link to https://a.storyblok.com/f/39898/3310x2192/e4ec08624e/demo-image.jpeg you can use the asset link type.

In the case of a link to the asset, the linktype value is set to asset. You can find the full URL of the asset in the url field.

"cta": {
  "id": "",
  "url": "https://a.storyblok.com/f/39898/3310x2192/e4ec08624e/demo-image.jpeg",
  "linktype": "asset",
  "fieldtype": "multilink",
  "cached_url": "https://a.storyblok.com/f/39898/3310x2192/e4ec08624e/demo-image.jpeg"
},

If you are using an image as an asset, you can create a link in the frontend using the URL found in the url field, and you can use the Storyblok Image Service features.

Another popular example of using asset link type is when you want to create a link to a document. The asset uploaded on the Storyblok asset management system is a PDF document (for example), and you can make the link to the document via the asset link type.

If you need to create a link to an email address, for example, a "mailto" link, you can use the email link type.

In the case of a link to the email address, the linktype field is set to email value, and you can find the full email address in the url and email field.

"cta": {
  "id": "",
  "url": "info@storyblok.com",
  "email": "info@storyblok.com",
  "linktype": "email",
  "fieldtype": "multilink",
  "cached_url": "info@storyblok.com"
},

On the frontend side, to create a "mailto" link, you need to use the HTML <a> tag with its href attribute and insert a "mailto:" parameter concatenating the value of email field.

Section titled The Story link type The Story link type

If you need to create a link to an internal story or page you can use the Internal link option. In the UI, content editors can select a story, and from the API perspective you can retrieve an object like this:

"cta": {
  "id": "968c28c0-4f80-4478-b59e-ccbdf51d2fb7",
  "url": "",
  "linktype": "story",
  "fieldtype": "multilink",
  "cached_url": "home"
},

As you can see, the most relevant information you can get here is the UUID of the linked story in the id field. The url field is empty, and the cached_url is not always updated for caching reasons. So to retrieve some information coming from the linked story, you have to add a parameter during the API call to resolve the linked story and obtain more information.

The parameter is resolve_links, allowing multiple values: url, link, or story. Which value to use for the resolve_links parameter depends on what you'd like to get from the linked story.

ParameterValueTransforms Limit
resolve_linksurl500
resolve_linkslink500
resolve_linksstory50

Section titled Resolving a link to a story with "url" Resolving a link to a story with "url"

If you only want to obtain the information necessary to retrieve the path to access the story, you can set the resolve_links parameter to url.

This allows you to access a links array of link objects included in the response at the root level of the JSON.

Here is an example of the resolved links at the root level of the JSON response from the API for resolve_links=url :

{
    "story": {},
    "cv": 1687532464,
    "rels": [],
    "links": [
        {
            "name": "Managing region",
            "id": 297849231,
            "uuid": "405c3037-6729-4b34-99cb-e361c636be6a",
            "slug": "managing-region",
            "url": "articles/managing-region",
            "full_slug": "articles/managing-region"
        },
        {
            "name": "Home",
            "id": 296364320,
            "uuid": "968c28c0-4f80-4478-b59e-ccbdf51d2fb7",
            "slug": "home",
            "url": "/",
            "full_slug": "home"
        }
    ]
}

Now with the information retrieved from the JSON: the UUID of the linked story in the link object in the story, you can access the right resolved link in the links array selected by the uuid field for accessing to the full_slug field.

Section titled Resolving a link to a story with "link" Resolving a link to a story with "link"

With the same approach, you can use the link value for the resolve_links parameter.

The link value can allow access to additional information like the path, parent_id, is_folder, published, is_startpage, position and real_path.

Here is an example of the resolved links at the root level of the JSON response from the API for resolve_links=link :

{
    "story": {},
    "cv": 1687532464,
    "rels": [],
    "links": [
        {
            "id": 297849231,
            "uuid": "405c3037-6729-4b34-99cb-e361c636be6a",
            "slug": "managing-region",
            "path": null,
            "parent_id": 297216277,
            "name": "Managing region",
            "is_folder": false,
            "published": false,
            "is_startpage": false,
            "position": -10,
            "real_path": "/managing-region"
        },
        {
            "id": 296364320,
            "uuid": "968c28c0-4f80-4478-b59e-ccbdf51d2fb7",
            "slug": "home",
            "path": "/",
            "parent_id": 0,
            "name": "Home",
            "is_folder": false,
            "published": true,
            "is_startpage": false,
            "position": 0,
            "real_path": "/"
        }
    ]
}

Using resolve_links=link you can access the links array, and for each item, you can retrieve the real path via real_path attribute.

Section titled Resolving a link to a story with "story" Resolving a link to a story with "story"

If, for some reason, you want to access all the information of the linked stories and you want to retrieve the whole JSON of the linked story, you can set the resolve_links parameter to story.

Here is an example of the resolved links at the root level of the JSON response from the API for resolve_links=story:

{
    "story": {},
    "cv": 1687532464,
    "rels": [],
    "links": [
        {
            "name": "Managing region",
            "created_at": "2023-04-25T19:53:52.946Z",
            "published_at": null,
            "id": 297849231,
            "uuid": "405c3037-6729-4b34-99cb-e361c636be6a",
            "content": {
                "_uid": "44b32ba5-5c99-46c9-b88e-ed95d2f0692d",
                "image": {
                    "id": 9063468,
                    "alt": "",
                    "name": "",
                    "focus": "",
                    "title": "",
                    "source": "",
                    "filename": "https://a.storyblok.com/f/224825/6000x4000/9a450e8023/greg-rosenke-1tjort2dlow-unsplash.jpg",
                    "copyright": "",
                    "fieldtype": "asset",
                    "meta_data": {},
                    "is_external_url": false
                },
                "title": "Managing Region",
                "teaser": "With Storyblok, you can choose the region EU or US when you create the space.",
                "subtitle": "Managing region with Storyblok",
                "component": "article",

... continue ...

In this case, you can access the story object in the links array, via the story's UUID (the uuid attribute), and you can also access the whole content of the story and its nested components via the content attribute.

Now you understand the link types you can manage with Storyblok, the way to obtain the URLs according to the specific link type, and how to resolve the link to the linked stories (internal link), we can try to use the Universal JavaScript SDK for Storyblok's API and try to understand how it can make our lives easier, especially when retrieving information (URLs) with internal links (stories).

It is possible to resolve links two levels deep by setting resolve_links_level parameter to 2 (Default: 1). If a story contains link fields that reference other stories, which also contain link fields, by default, the links contained in the referenced stories are not resolved. However, by utilizing the resolve_links_level parameter, these links can also be resolved and will be added to the rels array of the API response. This approach is compatible with the url, link, and story methods explained above.

Section titled Using the Storyblok's JavaScript Client Using the Storyblok's JavaScript Client

If you want to resolve and retrieve the URL for a linked story and use the resolve_links parameter while calling the API, you have to take two steps to parse the JSON response. The first is retrieving the UUID of the linked story in the id field in the component with linktype set as story in the main story and then retrieving the right link object from the links array.

To simplify this process, the advice is to use the JavaScript client provided by Storyblok https://github.com/storyblok/storyblok-js-client. Moreover, using the JavaScript client in a real application or project has several benefits such as:

  • Setting the rate limit (performing API throttling)
  • Access to Content Delivery API and Management API
  • Manage the data caching
  • Manage timeout
  • Manage max retries
  • Resolve the relationship between stories
  • Resolving links (expanding link object with the needed information)
  • Allows your own response interceptor
  • Provides a convenient method for getting all the items in case you need to retrieve all the data from an endpoint and walk through the pagination.

You can install storyblok-js-client using your favorite package manager. For example, using npm, you can run npm i storyblok-js-client -D.

In the following JavaScript snippet code, you are going to:

  • import the StoryblokClient
  • initialize the StoryblokClient with an access token
  • perform the API call for retrieving the story with the 'home' slug
  • set the resolve_links parameter to url
  • access the link object in the story
  • access the links array
        
      // 001 : importing the package
import StoryblokClient from "storyblok-js-client";
// 002 : initializing the client with the Stroyblok access token
const Storyblok = new StoryblokClient({
	accessToken: 'your_access_token',
});

// 003 : performing the API request, in this case the GET retrieving the `home` story
Storyblok.get('cdn/stories/home', {
	version: 'draft',
// 004 : setting the resolve_links parameter with 'url' value
+	resolve_links: 'url'
}).then((response) => {
	console.log('***************** STORY ***')
// 005 : accessing to the component
	console.log(response.data.story.content.body[4].cta)

	console.log('***************** LINKS ***')
// 006 : accessing to the links array
	console.log(response.data.links)
}).catch((error) => {
	console.log(error)
})

    

The link object retrieved in the story and returned by the JavaScript library will contain more information than the API response just because the JavaScript library will pick some information from the links array and inject the information into the link object found in the story. For example, an object like this will be available, allowing you to easily access the resolved information:

{
  id: '968c28c0-4f80-4478-b59e-ccbdf51d2fb7',
  url: '',
  linktype: 'story',
  fieldtype: 'multilink',
  cached_url: 'home',
  story: {
    name: 'Home',
    id: 296364320,
    uuid: '968c28c0-4f80-4478-b59e-ccbdf51d2fb7',
    slug: 'home',
    url: '/',
    full_slug: 'home',
    _stopResolving: true
  }
}

As you can see, you have a link object with the linktype set to the story value and a new field story with some data of the linked story.

If you use story instead of url for the resolve_links parameter, you will find the whole linked story object.