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.
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.
The URL link type
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
.
The asset link type
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.
The email 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.
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.
Parameter | Value | Transforms Limit |
---|---|---|
resolve_links | url | 500 |
resolve_links | link | 500 |
resolve_links | story | 50 |
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.
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.
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).
Resolving links two levels deep
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.
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 tourl
- access the link object in the story
- access the
links
array
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.