What are Strapi lifeCycle hooks and how to use them in v4?

What are Strapi lifeCycle hooks and how to use them in v4?

Strapi, the open-source headless CMS. One of the standout features of Strapi is its lifecycle hooks, which allow you to extend the default behavior of your API and perform custom actions at specific points. In this blog post, we will explore what Strapi lifecycle hooks are, why they are valuable, and how to leverage them to enhance your API functionality. Whether you're new to Strapi or an experienced user, mastering lifecycle hooks will unlock exciting possibilities for your projects. So, let's dive in and understand everything you need to know about Strapi lifecycle hooks.

In this blog post, we will cover the following topics:

  1. What are lifecycle hooks?

  2. Why are lifecycle hooks important?

  3. The different types of lifecycle hooks in Strapi.

  4. How to use lifecycle hooks in your Strapi project.

By the end of this blog post, you will have a comprehensive understanding of Strapi's lifecycle hooks and feel confident in utilizing them to customize your API according to your specific requirements. So, without further ado, let's jump into the world of Strapi lifecycle hooks!

When you Create, Update, and Delete a Strapi entry from collection types some hooks run. Now, you can do a lot of things using these lifecycle hooks.
I mostly use it to

  1. Validate and sanitize strapi inputs.

  2. Create a custom slug.

  3. Send data to a different cloud database for ex: Elastic Search

There are many lifeCycle hooks in Strapi some of the most used hooks are

  1. beforeCreate

  2. beforeUpdate

  3. afterCreate

  4. afterUpdate

You can find many more hooks in the documentation.

How can I start using hooks?
To create a hook:
1. go to ./api/[api-name]/content-types/[content-type-name]/ In my Strapi project, I have created a "Customer" collection type so my hooks path is : src/api/customer/content-types/customer/lifecycles.js
2. create lifecycles.js file.

Now you are ready to create and use hooks.

Inside lifecycles.js I have written this hook.

// src/api/customer/content-types/customer/lifecycles.js
module.exports = {
    beforeCreate(event) {
        console.log(event.params.data)
    },
};

// result
{
  Name: 'Sajib',
  Email: 'sajib@gmail.com',
  Plan: 'Basic',
  StoreName: 'Saj Store',
  Address: 'Dhaka, Bangladesh',
  createdBy: 1,
  updatedBy: 1,
  publishedAt: null,
  createdAt: 2023-10-01T15:25:09.975Z,
  updatedAt: 2023-10-01T15:25:09.975Z
}

Here you can see when I added an entry from the Strapi dashboard it ran this hook.
Now this hook has many objects if you console.log the "event" parameter then you will see it contains data such as model, lifecycles, state, params, etc.

Now, Let's see a real-world example. for my "Customer" collection I want to create a "slug" field that can't be editable from the UI dashboard and it will be automatically created when we create an entry. To achieve this:

1. Go to "Content-Type builder" and then "Customer" collection
2. Click "Add additional field" select text and give it a name. ex: slug
3. after saving, click on "Configure the view" and click on the edit icon of the slug
4. Set the editable field to false.

Now we can generate the slug from our "afterCreate" hook. we can't use "beforeCreate" because then we will not get the "id" of the entry.

const slug = require('slug')
const randomstring = require("random-string-gen");
const { errors } = require('@strapi/utils');
const { ApplicationError } = errors;

module.exports = {
    async afterCreate(event) {
        try {
            const { Name, Address, id } = event.result
            const url_slug = slug(`${Name} ${Address} ${randomstring(7)}`)

            await strapi.db.query('api::customer.customer').update({
                where: { id: id },
                data: {
                    Slug: url_slug
                }
            });
        } catch (error) {
            throw new ApplicationError("Something went wrong");
        }
    }
};

  1. Here I have installed 2 packages, slug and range-string-gen using yarn.

  2. I have created an "afterCreate" hook. this will run after Strapi has created the entry.

  3. in lines 9-10, I have extracted "Name", "Address", and "id" from event.result and generated a unique slug. you can also use Crypto to generate a unique slug

  4. in line number 12 I am using Strapi Query-Engine-API and updating the slug of the entry.

  5. I have also used a try-catch block and handled exceptions. you can learn more about this from the documentation.

  6. After I saved the entry, it ran the "afterCreate" hook and automatically generated the slug. As you can see the "slug" field is not editable from the UI dashboard.

So, this is a small demo of Strapi lifeCycle hooks. There are many real-world scenarios where you can use the lifecycle hooks.

I hope you learned something from this blog. If you have any suggestions to make this blog better then please, write in the comment.

Source code: https://github.com/sajibhn/strapi-hooks