Skip to content

Handling URL Path and Story slug

How the URL path determines the story slug

|
Handling URL Path and Story slug

Routing is often one of the first things developers overcomplicate when building a website with a headless CMS.

In reality, Storyblok allows you to keep routing extremely simple.

The idea is straightforward:

The URL path determines the story slug.

With this single principle, you can handle:

  • simple pages

  • nested pages

  • multilingual websites

  • non-Latin URLs with transliteration

All with the same routing logic.

No complex configuration.
No custom routing layers.
Just a predictable structure that mirrors your Storyblok content tree.

Let’s break it down step by step.


Level 1: Simple path = Simple slug

URL

yoursite.com/about

Slug

/about

What happens

The application reads the URL path and fetches the story with slug /about using the Content Delivery API.

Routing logic

  1. Get the URL path

  2. Use it as the slug

  3. Fetch the story

That’s it. This is the most basic and clean routing approach you can implement with Storyblok.


Level 2: Nested paths = Nested folders

URL

yoursite.com/about/company

Slug

/about/company

What happens

The application fetches the story /about/company.

Why this works

Storyblok organizes content in folders and stories that naturally mirror a website structure.

So if your content tree looks like this:

about
  └── company

The URL automatically matches the slug.

Routing logic

Exactly the same as before

  1. read path

  2. use as slug

  3. fetch story

No additional logic required.

This makes the routing system scalable by default.


Level 3: Multilingual Routing

Now let’s introduce languages.

URL

yoursite.com/en/something

Language

en

Slug

/something

What happens

Fetch the story with:

slug: /something
language: en
API call: /stories/something?language=en

Routing logic

  1. Split the URL path

  2. First segment = language

  3. Remaining path = slug

  4. Fetch the story with the language parameter

This allows you to manage multiple languages in Storyblok while keeping URLs clean and consistent.

URL path structure example

You have two options for multilingual slugs:

1. Same slug for all languages

/en/about
/de/about
/it/about
  • Story slug stays the same in every language

  • Only the content is translated

2. Translate the slug per language (via Translatable Slug application)

/en/about
/de/ueber-uns
/it/chi-siamo
  • Slug itself is translated to match the language

  • Provides fully localized URLs that are SEO-friendly

Both approaches work seamlessly with Storyblok’s routing model. You choose based on your SEO and localization needs.


Level 4: Transliteration for Non-Latin URLs

Some languages use non-Latin characters in URLs.

URL

yoursite.com/ru/продать

Language

ru

URL segment

продать

Transliterated slug

/prodat

What happens

Fetch the story with:

slug: /prodat
language: ru

Routing logic

  1. Split URL

  2. First segment = language

  3. Remaining path = transliterated to Latin

  4. Use transliterated value as slug

  5. Fetch the story

This approach allows:

  • clean URLs in local languages

  • consistent Latin slugs in Storyblok

  • predictable routing logic

It keeps the content structure stable while supporting global audiences.

Transliteration Reference

Non-Latin characters in the URL are converted to their Latin equivalents for the slug:

URL path

Language

Transliterated slug

/ru/продать

ru

/prodat

/ru/купить

ru

/kupit

/ar/مرحبا

ar

/mrhba

/zh/你好

zh

/ni-hao

Tool: https://yf-hk.github.io/transliteration/


The Core Principle

The entire routing system can be summarized in one simple flow.

┌─────────────────────────────────────────────────────┐
│                    URL PATH                         │
│         yoursite.com / [lang] / [path...]           │
└──────────────┬──────────────────┬───────────────────┘
               │                  │
          ┌────▼───-─┐    ┌───────▼────────┐
          │Language  │    │ Slug           │
          │parameter │    │ (transliterate │
          │(optional)│    │  if needed)    │
          └────┬─────┘    └───────┬────────┘
               │                  │
        ┌──────▼──────────────────▼──────┐
        │  Content Delivery API call     │
        │  GET /stories/[slug]?lang=[ln] │
        └────────────────────────────────┘

One routing rule. All scenarios covered.

Why This Approach Works Well with Storyblok

This routing model fits perfectly with Storyblok’s architecture.

  • Content structure mirrors URLs: Folders and stories naturally define the URL structure.

  • Language is handled via parameters: No need for complex routing configurations.

  • Slugs stay consistent: Even with multilingual and non-Latin content.

  • Frontend stays simple

Your application only needs:

  • path parsing

  • optional language detection

  • API request

Nothing more.


Final Takeaway

If you remember one thing, remember this:

In Storyblok, the URL path should define the story slug.

Everything else builds on top of this rule.

Simple pages → path equals slug
Nested pages → folders match URL
Multilingual → first segment is language
Non-Latin URLs → transliterate and fetch

One rule.

Minimal routing.

Maximum scalability.

Story Drops

For developers and Storyblok power editors who already know the basics and want to go further. Story Drops is a collection of opinionated tips — each one focused, practical, and honest about trade-offs. No best-practice rewrites. Just real patterns from real projects.


Roberto 2026