Using same slug on different locales

Hello All :grinning_face_with_smiling_eyes:

I’m having an issue using slug search with internationalization plugin.

It’s possible to use the same slug but change the _locale parameter? Strapi doesn’t allow me to use the same slug for different languages.

Thanks in advance

I am having the same issue, have you figured it out? thanks

I’m experiencing the same problem. I want to have same slug for EN and FR pages. Example: /academy and /fr/academy. But slug field doesn’t allow to do this. Is there any solution for it?

Hope this helps:
If you decide to not use “unique slug” you can adjust your models beforeCreate & beforeUpdate and check for uniqueness by querying with the current _locale.

1 Like

Has anyone here come up with a solution?

I have fixed by the following lifecycle addon:

By adding this lifecycle, when the slug fieldis is empty it will gen the slug from the title field, the slug will only genetrate in the en locale.

The slug field:

    "slug": {
      "pluginOptions": {
        "i18n": {
          "localized": false
        }
      },
      "type": "string",
      "unique": false,
      "regex": "^[a-z0-9]+(?:-[a-z0-9]+)*$"
    }

The lifecycle.js put under ./api/[api-name]/content-types/[content-type-name]/ folder, replace all api::blog.blog to api::[your-api-name]:

let slugify = require("slugify");
const { ApplicationError } = require("@strapi/utils").errors;

module.exports = {
  async beforeCreate(event) {
    await generateSlug(event);
  },

  async beforeUpdate(event) {
    await generateSlug(event);
  },
};

const generateSlug = async (event) => {
  const DEFAULT_LOCALE = "en";
  const { data } = event.params;
  const id = event.params?.where?.id ?? null;
  const locale = !id ? "en" : await getLocale(id);

  //Generate slug for en locale only
  if (!data.slug && data.title && locale == DEFAULT_LOCALE) {
    data.slug = slugify(data.title, { lower: true });
  }

  if (!data.slug) {
    throw new ApplicationError("Slug is required!");
  }
};

const getLocale = async (id) => {
  const res = await strapi.service("api::portfolio.portfolio").findOne(id);

  return res.locale;
};

2 Likes

Did any one find a solution?

I managed to register an entry translation with same slug as first language.

To do so I :

1) dropped unique constraint from database (postgresql here):

ALTER TABLE public.services DROP CONSTRAINT services_slug_unique

2) And then changed JS model for slug, from “uid” to “string”:

/src/api/service/content-types/service/schema.json

Original:
“slug”: {
“type”: “uid”,
“targetField”: “title”
},

Fixed:
“slug”: {
“type”: “string”,
“targetField”: “title”
},

I also did “npm run build” and restarted strapi container.

I intend to raise a new unique constraint, now adding locale as part of it:
ALTER TABLE public.services ADD CONSTRAINT services_slug_unique UNIQUE (slug, locale).

running latest api/strapi versions here : 4.4.3 (but should work on ohter versions).

:+1:

Hi! See my answer !

Is there any solution for it?

Hi. How can we do the same in Strapi v^4?

How to do this?

Perfectly! This solved my problem.
Error handling sometimes does not work. But I turned it off. Seems to work fine =)