Skip to content

Languages, URLs and Parameters

Ekit allows you to build monolingual or multilingual websites without duplicating templates.
The displayed language, page, and content are automatically determined from the URL.

This document explains the URL model, language handling, and content parameters used by Ekit.


URL structure

Ekit uses a clean and SEO-friendly routing system based on path segments.

/[lang]/[view]/[slug]?param=value

  • lang (optional): language code (en, fr, de, …)
  • view: page name (template)
  • slug (optional): identifies a specific record
  • param=value (optional): query parameters for filtering or dynamic behavior

Examples

/
/fr
/en/blog
/fr/blog/my-article
/blog/my-article
/fr/blog/my-article?preview=true

URLs always start with a leading /.
This keeps routes explicit, predictable, and aligned with standard web routing conventions.


Routing rules

  • The language segment is optional
  • If present, the first segment defines the active language — only when it is one of the project's languages
  • The first page segment maps to the current view
  • If no view is present, index is used by default
  • The second page segment is used as the slug
  • Query parameters are optional and used for filtering or additional behavior

Route resolution

Example URL:

/fr/blog/my-article

Resolved parameters:

params = { lang: "fr", view: "blog", slug: "my-article" }


Language detection

The language is automatically inferred from the first URL segment.

  • If the first segment matches a configured language → it is used
  • Otherwise → the project’s default language is applied, and the first segment is read as the page name

This allows: - monolingual projects without configuration - shared templates across multiple languages


Language examples

URL Language View Slug
/fr/blog/ fr blog —
/fr/blog/post/ fr blog post
/blog/post/ defaultLang blog post (multilingual site: redirected to /en/blog/post/, see below)
/ defaultLang index —
/de/blog/ (German not in the project) defaultLang de — → 404, no page named de

Unknown language codes

If the first segment looks like a language but is not one of the project's languages:

/it/blog

it is read as a page name. Unless your site has a page called it, the address returns a 404. A language removed from a project therefore makes its old addresses return 404, which is what search engines expect.


Canonical addresses (redirects)

On a multilingual site, each page has one official address: /{language}/{page}/{slug}/, in lowercase and with a trailing slash. On the public address of the site, any other form of an existing page is redirected (301) to it, query string included:

Requested Redirected to
/blog /en/blog/ (default language)
/en/blog /en/blog/
/EN/blog/ /en/blog/
/en/index /en/
/en/blog/my-article/anything /en/blog/my-article/
/blog?utm_source=x /en/blog/?utm_source=x

Visitors and search engines always land on the same address, so a page is never indexed twice. The Studio preview and single-language sites are not affected. An address that matches no page is not redirected: it returns a 404 directly.

Links in your templates

Write internal links with the language and the trailing slash (/{{lang}}/blog/): they are served directly, without a redirect.


To ensure correct navigation between pages and languages, define a base URL in your layout.

In layouts/layout.hbs, inside the <head> section:

This guarantees consistent navigation and prevents malformed URLs when mixing relative and root-relative links.


Linking pages and languages

Always use root-relative links (starting with /).

Language switcher example

langs holds the project's languages (for example ["en", "fr"]). Build the switcher from it, so it only shows languages that exist, and hide it when the project has a single language:

{{#if langs.[1]}}
<ul>
  {{#each langs}}
  <li><a href="/{{this}}/" {{#if (eq this @root.lang)}}aria-current="true"{{/if}}>{{upper this}}</a></li>
  {{/each}}
</ul>
{{/if}}

Linking to a page

<a href="/fr/blog/">Blog (FR)</a>
<a href="/en/blog/">Blog (EN)</a>

Linking to a specific content (slug)

<a href="/fr/blog/my-article/">Article</a>

URL parameters (query string)

Query parameters can be used for filtering or dynamic behavior.

/blog?category=news
/blog/my-article?preview=true

They are available in templates via the query object.

Handlebars example

<p>Category: {{query.category}}</p>

Ekit uses slug-based routing as the primary way to identify content.

Example:

/fr/blog/my-article

In your datasource:

datasources:
  article:
    from: blog
    slug: "{{params.slug}}"

UID support (optional)

You can still use a uid when needed (internal or legacy usage).

datasources: article: from: blog uid: "{{query.uid}}"

Example:

/blog?uid=123

However, using slugs is recommended for:

  • SEO
  • readability
  • clean URLs

In templates

Routing values are accessible in templates:

{{params.lang}}
{{params.view}}
{{params.slug}}
{{query.xxx}}

Best practices

  • Use the path for navigation (lang, view, slug)
  • Use the query string for filtering or optional flags
  • Prefer slug over uid for content identification
  • Keep templates simple and data-driven
  • Use a single view for list and detail pages when possible

Summary

  • Ekit uses clean, SEO-friendly URLs
  • Language is inferred automatically
  • Routing is based on lang / view / slug
  • Slugs are the primary way to identify content
  • Query parameters are optional and complementary
  • Templates are shared across all languages

This model keeps projects simple, scalable, and easy to maintain.