blablabla
blablabla

Reputation: 69

How to create a dynamic slug in Strapi v4?

I want to create a slug for the url as soon as the user adds an event from the frontend. The slug is based on the name of the event. How to do that in V4 as the old method does not work now?

Slug creation link - old version

Upvotes: 2

Views: 4242

Answers (3)

Shubham Digole
Shubham Digole

Reputation: 73

In your Strapi project, you can create a lifecycles.js file inside the api/collection-name/content-type/collection-name folder. In this file, you can define the lifecycle methods to be executed for the specified content type.

     module.exports = {
             async beforeCreate(event) {

             // Generate slug using the 'plugin::content-manager.uid' service

             const slug = await strapi.service('plugin::content-manager.uid').generateUIDField({
             contentTypeUID: 'api::product.product'// Replace 'product' with your collection name,
             field: 'slug', // Replace 'slug' with the desired field name
             data: event.params.data
       }); 

         

         // Assign the generated slug to the 'slug' field
         event.params.data.slug = slug;

         // Assign the generated slug to the 'slug2' field (if needed)
         event.params.data.slug2 = slug;
       }
      };

Explanation:

  • The beforeCreate method is a lifecycle hook that is triggered before creating a new entry in the specified collection.

  • The beforeCreate method is a lifecycle hook that is triggered before creating a new entry in the specified collection.

  • Inside the beforeCreate method, the generateUIDField method from the plugin::content-manager.uid service is used to generate a unique slug for the entry.

  • The generateUIDField method requires the contentTypeUID, field, and data parameters. Make sure to replace 'product' with your actual collection name and 'slug' with the desired field name.

  • The generated slug is assigned to the slug field of the event.params.data object, which represents the data for the new entry.

  • If you need to assign the same slug to another field (e.g., slug2), you can add a line to assign the slug value to that field as well.

Note: Please make sure that the file is named lifecycles.js and placed in the correct folder structure as mentioned above.

Feel free to adjust the code according to your specific requirements, such as field names and collection names.

Upvotes: 2

atazmin
atazmin

Reputation: 5687

This seem to work for me

Settings > Roles > Public > Slugify (checkbox findSlug) config/plugins.js

module.exports = ({ env }) => ({
  slugify: {
    enabled: true,
    config: {
      contentTypes: {
        page: {
          field: "slug",
          references: "name",
        },
        post: {
          field: "slug",
          references: "name",
        },
        category: {
          field: "slug",
          references: "name",
        },
      },
    },
  },
});

graphql

const POSTS = gql`
  query GetPosts {
    posts {
      ... on PostEntityResponseCollection {
        data {
          __typename
          id
          attributes {
            __typename
            name
            slug
            content
            featuredImage {
              data {
                __typename
                id
                attributes {
                  url
                  alternativeText
                  caption
                }
              }
            }
            createdAt
          }
        }
      }
    }
  }
`;

const POST = gql`
  query GetPost($slug: String!) {
    findSlug(modelName: "post", slug: $slug, publicationState: "live") {
      ... on PostEntityResponse {
        data {
          __typename
          id
          attributes {
            createdAt
            name
            slug
            content
            seo {
              __typename
              id
              title
              description
              blockSearchIndexing
            }
            categories {
              __typename
              data {
                __typename
                id
                attributes {
                  __typename
                  name
                  slug
                }
              }
            }
          }
        }
      }
    }
  }
`;

Upvotes: 3

Jose Balanza Martinez
Jose Balanza Martinez

Reputation: 126

By following the article, it seems that you are trying to add lifecycle events to a model. You would need to make the following modifications to the article to make it work for v4.

After the creation of the article model via the admin dashboard, instead of adding the following file:

./api/article/models/Article.js

add:

./src/api/article/content-types/article/lifecycles.js

With the following:

const slugify = require('slugify');

module.exports = {
    async beforeCreate(event) {
      if (event.params.data.title) {
        event.params.data.slug = slugify(event.params.data.title, {lower: true});
      }
    },
    async beforeUpdate(event) {
      if (event.params.data.title) {
        event.params.data.slug = slugify(event.params.data.title, {lower: true});
      }
    },
};

Also the api endpoint changed in v4 so you would need to use:

GET /api/articles?filters[slug]=my-article-slug

Upvotes: 6

Related Questions