Localized Slugs and Preview Paths
When i18n is enabled for an entry collection, managing entry slugs (file names) across different locales can be challenging. Sveltia CMS offers two solutions: localized entry slugs and UUID-based slugs.
Localizing Entry Slugs
In Sveltia CMS, it’s possible to localize entry slugs (filenames) if the i18n structure is multiple_files or multiple_folders. All you need is the localize filter for slug template tags:
i18n:
structure: multiple_folders
locales: [en, fr]
slug:
encoding: ascii
clean_accents: true
collections:
- name: posts
label: Blog posts
folder: /content/posts
slug: '{{title | localize}}'
format: yaml
i18n: true
fields:
- name: title
label: Title
widget: string
i18n: true[i18n]
structure = "multiple_folders"
locales = ["en", "fr"]
[slug]
encoding = "ascii"
clean_accents = true
[[collections]]
name = "posts"
label = "Blog posts"
folder = "/content/posts"
slug = "{{title | localize}}"
format = "yaml"
i18n = true
[[collections.fields]]
name = "title"
label = "Title"
widget = "string"
i18n = true{
"i18n": {
"structure": "multiple_folders",
"locales": ["en", "fr"]
},
"slug": {
"encoding": "ascii",
"clean_accents": true
},
"collections": [
{
"name": "posts",
"label": "Blog posts",
"folder": "/content/posts",
"slug": "{{title | localize}}",
"format": "yaml",
"i18n": true,
"fields": [
{
"name": "title",
"label": "Title",
"widget": "string",
"i18n": true
}
]
}
]
}{
i18n: {
structure: "multiple_folders",
locales: ["en", "fr"],
},
slug: {
encoding: "ascii",
clean_accents: true,
},
collections: [
{
name: "posts",
label: "Blog posts",
folder: "/content/posts",
slug: "{{title | localize}}",
format: "yaml",
i18n: true,
fields: [
{
name: "title",
label: "Title",
widget: "string",
i18n: true,
},
],
},
],
}With this configuration, an entry is saved with localized filenames, while the default locale’s slug is stored in each file as an extra translationKey property, which is used in Hugo’s multilingual support. Sveltia CMS and Hugo read this property to link localized files.
For example, if you create a blog post with the title “My trip to New York” in English and “Mon voyage à New York” in French, the following files will be created:
content/posts/en/my-trip-to-new-york.yamlyamltranslationKey: my-trip-to-new-york title: My trip to New Yorkcontent/posts/fr/mon-voyage-a-new-york.yamlyamltranslationKey: my-trip-to-new-york title: Mon voyage à New York
You can customize the property name and value for a different framework or i18n library by adding the canonical_slug option to your top-level or collection-level i18n configuration. The example below is for @astrolicious/i18n, which requires a locale prefix in the value (discussion):
i18n:
canonical_slug:
key: defaultLocaleVersion # default: translationKey
value: 'en/{{slug}}' # default: {{slug}}[i18n]
canonical_slug = { key = "defaultLocaleVersion", value = "en/{{slug}}" }{
"i18n": {
"canonical_slug": {
"key": "defaultLocaleVersion",
"value": "en/{{slug}}"
}
}
}{
i18n: {
canonical_slug: {
key: "defaultLocaleVersion",
value: "en/{{slug}}",
},
},
}For Jekyll, you may want to use the ref property:
i18n:
canonical_slug:
key: ref[i18n]
canonical_slug = { key = "ref" }{
"i18n": {
"canonical_slug": {
"key": "ref"
}
}
}{
i18n: {
canonical_slug: {
key: "ref",
},
},
}In a nested collection, the slug names the entry’s folder, so localizing the slugs also gives every locale its own folder names.
Making Slugs Editable
To make slugs editable for each locale, you can set the slug option to {{fields._slug | localize}} in your collection configuration:
collections:
- name: posts
label: Blog Posts
folder: /content/posts
slug: "{{fields._slug | localize}}"[[collections]]
name = "posts"
label = "Blog Posts"
folder = "/content/posts"
slug = "{{fields._slug | localize}}"{
"collections": [
{
"name": "posts",
"label": "Blog Posts",
"folder": "/content/posts",
"slug": "{{fields._slug | localize}}"
}
]
}{
collections: [
{
name: "posts",
label: "Blog Posts",
folder: "/content/posts",
slug: "{{fields._slug | localize}}",
},
],
}Using Random UUIDs for Slugs
Entry titles and other fields containing non-Latin characters, such as Japanese or Chinese, may not be suitable for generating slugs. To address this issue, Sveltia CMS lets you use random UUIDs as slugs for entries in i18n collections.
This can be achieved by setting the slug option with the {{uuid}}, {{uuid_short}} or {{uuid_shorter}} template tag in your collection configuration:
collections:
- name: posts
label: Blog Posts
folder: /content/posts
slug: "{{uuid_short}}"[[collections]]
name = "posts"
label = "Blog Posts"
folder = "/content/posts"
slug = "{{uuid_short}}"{
"collections": [
{
"name": "posts",
"label": "Blog Posts",
"folder": "/content/posts",
"slug": "{{uuid_short}}"
}
]
}{
collections: [
{
name: "posts",
label: "Blog Posts",
folder: "/content/posts",
slug: "{{uuid_short}}",
},
],
}Preview Paths
When i18n is enabled for an entry collection, you can manage preview paths for each locale using the preview_path option. This option supports the {{locale}} template tag, which will be replaced with the current locale in the preview URL. For example, if you set the preview_path to /{{locale}}/{{slug}}, the preview URL for an entry with the slug my-post in the fr locale would be /fr/my-post.
The omit_default_locale_from_preview_path option can be used to omit the locale code from the preview path for the default locale. For example, if en is the default locale and omit_default_locale_from_preview_path is set to true, the preview URL for the English version of the entry would be /my-post, while the preview URL for the French version would still be /fr/my-post.
Both options apply to Deploy Previews as well, so each translation of an unpublished entry links to its own page on the preview build. The per-locale links are offered from the locale pane’s options menu in the Content Editor.