NextJs Prismic routes and Slugs translation

Hello,

We have a multilingual site. 3 languages to be precise: FR, EN, NL
We already have locale management with src/app/[locale]
but we have a problem with slugs. Our pages are www.domaine.com/news/:uid. For proper SEO, the slug should be translated into French. So as to have www.domaine.com/actu/:uid. We haven't found a clean way to do this. We could put conditions on lang in prismicio.ts and make directories src/app/[locale]/news and src/app/[locale]/actu, but that's redundant, risks duplicate code and is a security risk.
Do you have a cleaner, more standard method?
We've also tried "next-translate-routes", but it's not compatible with NextJS 14, on which our project is based.

const routes: prismic.ClientConfig["routes"] = [
  {
    type: "homepage",
    path: "/",
  },
  {
    type: "contactpage",
    path: "/contact",
  },
  {
    type: "newspage",
    path: "/news/:uid",
  },
  {
    type: "newslistpage",
    path: "/news",
  },
];

Hey @micha,

This should be possible with the route resolver:

You can do something like this:

  {
    type: "newspage",
    lang: "en-us",
    path: "/news/:uid",
  },
  {
    type: "newspage",
    lang: "fr-fr",
    path: "/actu/:uid",
  }

Does that work for you?

Sam

Hello Sam,

Yes, that will probably work, but we'll be duplicating the programming of the news directory twice. Having the code in three places isn't the best solution. If we fix the code in one place, we mustn't forget to fix it in the other two. It's prone to errors and not very optimized.

Hey @micha,

Have you looked at our i18n documentation?

I don't think you'll need to duplicate your programming. Take a look at the doc and let me know if you still have any questions.

Sam

Hello Sam,

Indeed, with a path: '/lang?/:uid' mechanism, there's no problem. All pages are at the root with their own UID. You could even consider the news list page as a page with its own UID.
We'd then have pages like:

www.site.com/en/news
www.site.com/en/news-1
www.site.com/fr/actus
www.site.com/fr/actus-1

This is probably where we'll be heading if there are no other solutions.

What I would have liked is the possibility of adding a translatable slug. Like in Symfony for example.

www.site.com/en/news
www.site.com/en/news/news-1
www.site.com/fr/actus
www.site.com/fr/actus/actu-1

Hey @micha,

If I understand correctly, this will accomplish what you want:

  {
    type: "newspage",
    lang: "en-us",
    path: "/news/:uid",
  },
  {
    type: "newspage",
    lang: "fr-fr",
    path: "/actu/:uid",
  }

I don't think you need to duplicate any programming here. You should still be fine with one file, /:lang/:uid. I think I'm misunderstanding, though. What's the blocker?

Sam

If I use

  {
    type: "newspage",
    lang: "en-us",
    path: "/news/:uid",
  },
  {
    type: "newspage",
    lang: "fr-fr",
    path: "/actu/:uid",
  }

I will have a 'news' directory and an 'actu' directory with the same files. That's what I mean by duplicate programming files. And I don't think we can create directory aliases in Versel.

Hey Micha,

I will have a 'news' directory and an 'actu' directory with the same files

That's not necessarily the case. You could have a file like app/[section]/[uid].js and dynamically read the section segment as news or actu to impute the language. You might create an object like this:

const sectionLangs = {
  news: "en-us",
  actu: "fr-fr"
}

Then in your query you would do something like this:

prismic.getByUID("page", params.uid,
  {
    lang: sectionLangs[params.section]
  }
)

Let me know if that makes sense :slight_smile:

Forgive me Sam but I come from the PhP world :)
Even if the developer in charge is qualified React, NextJS.
We've tried more but nothing is conclusive. I can't understand why there isn't a standard method for something as simple as managing url rewriting translation. It's imperative for any SEO optimization. Symfony, Laravel, WordPress, Prestashop, CRAFTcms, ... they all integrate the ability to have translated slugs.

www.site.com/en/news/news-1
and
www.site.com/fr/actus/actu-1

should have a simple prismic solution. Maybe define the slug method in the file.
But right now we're going in circles. And I'm a bit disappointed. Yes, it's simple if there's only one type of page and you only use UID. But in a real site, there are sections and categories.
I can't find any documentation with a real methodology to follow. A real best practice. It's a shame for a product of your quality.
Besides, I don't feel like I'm asking for the moon. After all, I'm not the only project in need of a translated section. I don't understand why there isn't a validated and usable beste pratice.

Hey @micha,

What you're describing is possible and straightforward with Prismic as far as I understand, so I think we can figure this out.

Could you describe the file structure of your project and the routing structure of your website for me?

Sam

Hello Sam,

Did you see my private message?

Kr

Micha

Hi Micha,

Thanks for sharing this detail. It seems like the problem is that the news/nieuws/actu segment is hard-coded in your application. If the name of the folder is news, then the URL segment can only be news/.... If you change the folder name to [news], then you can handle URLs in any language.

Let me know if you have any other questions!

Sam

I still can't figure out how to use [news]. Especially since there's also the same strategy for events, jobs, recipes and content slugs. We need to create constants and conditions. Your proposal remains unclear to me. Could you elaborate on your solution? This will probably help others
Thank you very much.

Hey @micha,

Here's an example implementation:

sam-240520-next-01.zip (96.0 KB)

You can see that the [section] segment does nothing expect create a placeholder for the URL. In theory, you could go to /fr-fr/dog/autre or /fr-fr/ostrich/autre. If you wanted, you could create an app/[lang]/[segment]/layout.ts file where you enforce some URL validation rules, to ensure that the URL segment matches your structure.

Sam