Translatable URLs or slugs (configured in Prismic CMS)

Hi there.

I am currently exploring the use of Prismic as a headless CMS for static multilingual websites based on NextJS. So far, I am really liking what I'm seeing, especially since the recent updates that introduced TypeScript support.

I am currently looking into how I could best implement translatable URLs into a website. I have been looking around, and I couldn't find a straight answer, so that's why I'm here.

Let's say I have a /products page in English (en-us) and a Dutch (nl-nl) /producten. Ideally, I would not manually create a mapping for this in the code.

Scenario

In an ideal situation:

  • the person using Prismic could specify their desired slug in the CMS (the last part: example.com/some-english-category/some-english product. The category name would be specified in a NextJS pages directory or dynamically via getStaticPaths).
  • the slugs can be different per language (/my-article vs /mijn-artikel)
  • the language switch on the static page can link to the translated version of the page (if it is available)
  • this all works on a static site with a private Prismic repo

Given this scenario, I don't think I can make pages/[lang]/[uid].tsx work as suggested on the route resolver page, but I hope I'm wrong here :slight_smile:

My findings

I did some testing. When I get my page by UID as follows...

export const getStaticProps: GetStaticProps = async () => {
  const page = await Client().getByUID("page", "home", {});

  return {
    props: { page },
  };
};

... and then log this page to the console, I notice the following options:

An alternative_languages array:

[
    {
        "id": "abcdefg",
        "uid": "home",
        "type": "page",
        "lang": "en-us"
    }
]

A slugs array, but that seems deprecated: What are Slugs?

When I query a single custom type (my footer) and select the homepage in a "Content Relationship" link and inspect its properties I don't see any custom fields from the static zone of my page besides the UID, so I can't just add a custom slug field (which can then be translated per locale) and query it this way I think.

const footer = await Client().getSingle("footer");
// logging footer.data.menuLinks[0].link (content relationship link) gives me
{
    "id": "abcdefg",
    "type": "page",
    "tags": [],
    "slug": "this-is-my-hero", // from the first slice??? Kind of odd
    "lang": "nl-nl",
    "first_publication_date": "2021-11-30T17:01:13+0000",
    "last_publication_date": "2021-12-24T15:16:40+0000",
    "uid": "home",
    "url": "/home",
    "link_type": "Document",
    "isBroken": false
}

A possible solution?

Something I thought of (but haven't tried) was:

  1. querying all Prismic documents in getStaticProps (because that would provide custom slug fields from the static zone thus allowing the CMS operator to specify their desired slug)
  2. computing the full URLs the same way I would in getStaticPaths
  3. and passing those translatable URLs for the same page as props to my page.

Do I have any other (better) options?

I'm still relatively new to using Prismic, so please tell me if I'm missing something :slight_smile:

Happy holidays :christmas_tree:

I was just informed about Fetch linked document fields with the REST API - Prismic via Twitter. Haven't looked into it yet, but it might be helpful.

1 Like

Hi @eddyvinck95,

Thanks for reaching out; I'm wondering if you have been able to solve the issue!

Please let us know if you need any further assistance.

Hi @Fares. It does seem like it will be the solution, but I have not gotten to that part of my project yet. I'll post an update once I can give this a try!

1 Like

Please let us know if you need any further assistance.

I (still) haven't gotten to the translations yet, but I stumbled upon this page which I think I missed before Internationalization with Next.js - Documentation - Prismic

I believe that while I was still very new to Prismic I was under the impression that the UID could not be different between translations, but it appears I was wrong as I just tested it and it works fine. I can't remember if I tried this before, so maybe it has been updated to allow this?

So [lang]/[uid].tsx could definitely work in that case. All you need to do is follow the steps on the page:

  1. Create a pages/[lang]/ directory
  2. Create the required dynamic routes in the directory, like pages/[lang]/[uid].tsx and pages/[lang]/[category]/[uid].tsx and implement getStaticPaths and getStaticProps accordingly.
  3. Add your language switch as explained
  4. Add a link resolver function

So going back to my original ideal scenario:

  1. the person using Prismic could specify their desired slug in the CMS (the last part: example.com/some-english-category/ some-english product . The category name would be specified in a NextJS pages directory or dynamically via getStaticPaths ).
  2. the slugs can be different per language (/my-article vs /mijn-artikel)
  3. the language switch on the static page can link to the translated version of the page (if it is available)
  4. this all works on a static site with a private Prismic repo

Point 1 and 2 can be achieved using the UID and making it different per language, point 3 and 4 can be done by following the examples in the docs I linked.

If you need any additional information about another Prismic document the fetchLinks parameter can be used, but it's not necessary for the translations.

I wanted to edit my original post to not throw off any potential visitors to this page, but it won't let me, so I'm going to mark this reply as the solution and hope people see it. :slightly_smiling_face:

Thanks for your feedback, @eddyvinck95, and for letting us know.