Repository: meilisearch/strapi-plugin-meilisearch (js)

Issue:
Possibility to use a content-type in multiple indexes
<!-- This is not an exhaustive model but a help. No step is mandatory. -->

**Description**
Not sure if it is a new feature request or a bug but:
Possibility to use a content-type in multiple indexes
Currently it is possible to create custom indexes and for example create a index called products with content-type Shoes and T-shirts

But once you create one you cannot re-use the content type for another index example "offers".

For my understanding it is possible to do it with meilisearch as you can add any information to any index but it is not possible with this plugin.

**Basic example**
An option could be to change the config of the plugin and instead write the content type name as root of the json, use instead the index name

currently the config looks like

```
module.exports = () => ({
  //...
  meilisearch: {
    config: {
      shirts: {
        indexName: 'products',
      },
      shoes: {
        indexName: 'products',
      },
    shirts: {
indexName: 'offers'. //THIS is not possible right now as overwrite previous index.
}
    },
  },
})
```
What I propose is 
```
module.exports = () => ({
  //...
  meilisearch: {
    config: {
      products: {
        contentType: ['shoes','t-shirt']
      },
      offers: {
         contentType: ['jackets','t-shirt']
      },
     
    },
  },
})
```
Or as it is right now but not overwriting previous information and being able to manage it over the admin panel. But I do believe it would be easier the first option.

Pull request description:
Handle multiple index names in strapi config
# Pull Request

## Related issue
Fixes #651 

## What does this PR do?

This Pull Request introduces the capability to associate a single collection with multiple index names within Strapi's configuration. Previously, the indexName parameter was limited to a single string value, specifying one index per collection. Now, indexName can be defined as an array, enabling a collection to be indexed under multiple names simultaneously.

For example, the configuration can now be specified as:

Before: indexName: "my_restaurant"
After: indexName: "my_restaurant"  (after review, found a way to avoid the breaking change)
After: indexName: ["my_restaurant"]
After: indexName: ["my_restaurant", "all_restaurants"]
Additionally, this update includes the introduction of new tests to ensure that the expanded functionality does not disrupt existing features. An existing test was also corrected.

Important Changes:

**Limitation:** While indexName can now accept multiple values, all other configuration attributes remain uniform across the specified indexes. This means that any update to one index will apply identically to all indexes associated with a given collection, reflecting the same settings and data.


This enhancement provides greater flexibility in managing index names for collections within Strapi, streamlining the process of data organization and retrieval across multiple indexes.

### Result
![image](https://github.com/meilisearch/strapi-plugin-meilisearch/assets/117728108/33d6c8aa-8558-40d0-8fa4-14b3551811d1)
![image](https://github.com/meilisearch/strapi-plugin-meilisearch/assets/117728108/3baee28b-23a6-4766-a828-ebf52175c895)


## PR checklist
Please check if your PR fulfills the following requirements:
- [x] Does this PR fix an existing issue, or have you listed the changes applied in the PR description (and why they are needed)?
- [x] Have you read the contributing guidelines?
- [x] Have you made sure that the title is accurate and descriptive of the changes?

Thank you so much for contributing to Meilisearch!


Patch:
diff --git a/README.md b/README.md
index 2f5bbd8..c6127d2 100644
--- a/README.md
+++ b/README.md
@@ -217,9 +217,11 @@ Settings:
 
 By default, when indexing a content-type in Meilisearch, the index in Meilisearch has the same name as the content-type. This behavior can be changed by setting the `indexName` property in the configuration file of the plugin.
 
-**Example:**
+To link a single collection to multiple indexes, you can assign an array of index names to the `indexName` property.
 
-In the following example, the `restaurant` content-type in Meilisearch is called `my_restaurant` instead of the default `restaurant`.
+**Example 1: Linking a Single Collection to a Single Index**
+
+In the following examples, the `restaurant` content-type in Meilisearch is called `my_restaurant` instead of the default `restaurant`.
 
 ```js
 // config/plugins.js
@@ -236,6 +238,21 @@ module.exports = () => ({
 })
 ```
 
+```js
+// config/plugins.js
+
+module.exports = () => ({
+  //...
+  meilisearch: {
+    config: {
+      restaurant: {
+        indexName: ["my_restaurants"],
+      }
+    }
+  }
+})
+```
+
 It is possible to bind multiple content-types to the same index. They all have to share the same `indexName`.
 
 For example if `shoes` and `shirts` should be bound to the same index, they must have the same `indexName` in the plugin configuration:
@@ -248,10 +265,10 @@ module.exports = () => ({
   meilisearch: {
     config: {
       shirts: {
-        indexName: 'products',
+        indexName: ['products'],
       },
       shoes: {
-        indexName: 'products',
+        indexName: ['products'],
       },
     },
   },
@@ -260,6 +277,25 @@ module.exports = () => ({
 
 Now, on each entry addition from both `shoes` and `shirts` the entry is added in the `product` index of Meilisearch.
 
+**Example 2: Linking a Single Collection to Multiple Indexes**
+
+Suppose you want the `restaurant` content-type to be indexed under both `my_restaurants` and `all_food_places` indexes in Meilisearch. You can achieve this by setting the `indexName` property to an array containing both index names, as shown in the configuration below:
+
+```js
+// config/plugins.js
+
+module.exports = () => ({
+  //...
+  meilisearch: {
+    config: {
+      restaurant: {
+        indexName: ['my_restaurants', 'all_food_places'],
+      }
+    }
+  }
+})
+```
+
 
 **disclaimer**
 
diff --git a/playground/config/plugins.js b/playground/config/plugins.js
index 12454f3..9f21182 100644
--- a/playground/config/plugins.js
+++ b/playground/config/plugins.js
@@ -15,16 +15,16 @@ module.exports = ({ env }) => ({
             categories: entry.categories.map(category => category.name)
           };
         },
-        indexName: "my_restaurant",
+        indexName: ["my_restaurant"],
         settings:  {
           "searchableAttributes": ["*"]
         }
       },
       "about-us": {
-        indexName: "content",
+        indexName: ["content"],
       },
       homepage: {
-        indexName: "content",
+        indexName: ["content"],
       },
       // host: "http://localhost:7700",
       // apiKey: "masterKey"
diff --git a/resources/custom-index-name/custom-index-name.js b/resources/custom-index-name/custom-index-name.js
index a65ba6f..6d128f9 100644
--- a/resources/custom-index-name/custom-index-name.js
+++ b/resources/custom-index-name/custom-index-name.js
@@ -1,13 +1,14 @@
 // `shirts` and `pants` will be indexed in the same `products` index.
+// `tops` will also be indexed in a separate `tops` index.
 module.exports = () => ({
   //...
   meilisearch: {
     config: {
       shirts: {
-        indexName: 'products',
+        indexName: ['products', 'tops'],
       },
       pants: {
-        indexName: 'products',
+        indexName: ['products'],
       },
     },
   },
diff --git a/server/__mocks__/strapi.js b/server/__mocks__/strapi.js
index e6426a3..6e4fa2c 100644
--- a/server/__mocks__/strapi.js
+++ b/server/__mocks__/strapi.js
@@ -39,6 +39,10 @@ function createStrapiMock({
         ApiKeyIsFromConfigFile: true,
         HostIsFromConfigFile: true,
       }),
+      getIndexedContentTypes: () => [
+        'api::restaurant.restaurant',
+        'api::about.about',
+      ],
       actionInBatches: mockActionInBatches,
       addIndexedContentType: mockAddIndexedContentType,
       subscribeContentType: () => {
diff --git a/server/bootstrap.js b/server/bootstrap.js
index d877eaa..0a8a595 100644
--- a/server/bootstrap.js
+++ b/server/bootstrap.js
@@ -37,12 +37,16 @@ async function syncIndexedCollections({
   const contentTypes = contentTypeService.getContentTypesUid()
 
   for (const contentType of contentTypes) {
-    const indexUid = meilisearch.getIndexNameOfContentType({ contentType })
-    const indexInMeiliSearch = indexUids.includes(indexUid)
+    const contentTypeIndexUids = await meilisearch.getIndexNamesOfContentType({
+      contentType,
+    })
+    const indexesInMeiliSearch = contentTypeIndexUids.some(indexUid =>
+      indexUids.includes(indexUid),
+    )
     const contentTypeInIndexStore = indexedContentTypes.includes(contentType)
 
     // Remove any collection that is not in Meilisearch anymore
-    if (!indexInMeiliSearch && contentTypeInIndexStore) {
+    if (!indexesInMeiliSearch && contentTypeInIndexStore) {
       await store.removeIndexedContentType({ contentType })
     }
   }
diff --git a/server/configuration-validation.js b/server/configuration-validation.js
index 2731f81..0c0aad3 100644
--- a/server/configuration-validation.js
+++ b/server/configuration-validation.js
@@ -182,13 +182,21 @@ function CollectionConfig({ collectionName, configuration }) {
 
   return {
     validateIndexName() {
-      // indexName is either undefined or a none empty string
+      // indexName is either undefined, a non-empty string, or a non-empty array of non-empty strings
+      const isStringAndNotEmpty =
+        typeof indexName === 'string' && indexName !== ''
+
+      const isArrayWithNonEmptyStrings =
+        Array.isArray(indexName) &&
+        indexName.length > 0 &&
+        indexName.every(name => typeof name === 'string' && name !== '')
+
       if (
-        (indexName !== undefined && typeof indexName !== 'string') ||
-        indexName === ''
+        indexName !== undefined &&
+        !(isStringAndNotEmpty || isArrayWithNonEmptyStrings)
       ) {
         log.error(
-          `The "indexName" option of "${collectionName}" should be a non-empty string`,
+          `The "indexName" option of "${collectionName}" should be a non-empty string or an array of non-empty strings`,
         )
       } else if (indexName !== undefined) {
         options.indexName = indexName
diff --git a/server/services/meilisearch/config.js b/server/services/meilisearch/config.js
index 4f3b979..ccf93fe 100644
--- a/server/services/meilisearch/config.js
+++ b/server/services/meilisearch/config.js
@@ -21,18 +21,23 @@ module.exports = ({ strapi }) => {
   const contentTypeService = strapi.plugin('meilisearch').service('contentType')
   return {
     /**
-     * Get the name of the index from Meilisearch in which the contentType content is added.
+     * Get the names of the indexes from Meilisearch in which the contentType content is added.
      *
      * @param {object} options
      * @param {string} options.contentType - ContentType name.
      *
-     * @return {String} - Index name
+     * @return {String[]} - Index names
      */
-    getIndexNameOfContentType: function ({ contentType }) {
+    getIndexNamesOfContentType: function ({ contentType }) {
       const collection = contentTypeService.getCollectionName({ contentType })
 
       const contentTypeConfig = meilisearchConfig[collection] || {}
-      return contentTypeConfig.indexName || collection
+
+      let indexNames = [contentTypeConfig.indexName]
+        .flat(2)
+        .filter(index => index)
+
+      return indexNames.length > 0 ? indexNames : [collection]
     },
 
     /**
@@ -171,10 +176,10 @@ module.exports = ({ strapi }) => {
         contentTypeService.getCollectionName({ contentType }),
       )
       const contentTypeWithIndexName = collectionNames.filter(contentType => {
-        const name = this.getIndexNameOfContentType({
+        const names = this.getIndexNamesOfContentType({
           contentType,
         })
-        return name === indexName
+        return names.includes(indexName)
       })
       return contentTypeWithIndexName
     },
diff --git a/server/services/meilisearch/connector.js b/server/services/meilisearch/connector.js
index 16c0bf4..597121d 100644
--- a/server/services/meilisearch/connector.js
+++ b/server/services/meilisearch/connector.js
@@ -82,7 +82,7 @@ module.exports = ({ strapi, adapter, config }) => {
     },
 
     /**
-     * Delete multiples entries from the contentType in its index in Meilisearch.
+     * Delete multiples entries from the contentType in all its indexes in Meilisearch.
      *
      * @param  {object} options
      * @param  {string} options.contentType - ContentType name.
@@ -94,22 +94,30 @@ module.exports = ({ strapi, adapter, config }) => {
       const { apiKey, host } = await store.getCredentials()
       const client = Meilisearch({ apiKey, host })
 
-      const indexUid = config.getIndexNameOfContentType({ contentType })
+      const indexUids = config.getIndexNamesOfContentType({ contentType })
       const documentsIds = entriesId.map(entryId =>
         adapter.addCollectionNamePrefixToId({ entryId, contentType }),
       )
 
-      const task = await client.index(indexUid).deleteDocuments(documentsIds)
+      const tasks = await Promise.all(
+        indexUids.map(async indexUid => {
+          const task = await client
+            .index(indexUid)
+            .deleteDocuments(documentsIds)
+
+          strapi.log.info(
+            `A task to delete ${documentsIds.length} documents of the index "${indexUid}" in Meilisearch has been enqueued (Task uid: ${task.taskUid}).`,
+          )
 
-      strapi.log.info(
-        `A task to delete ${documentsIds.length} documents of the index "${indexUid}" in Meilisearch has been enqueued (Task uid: ${task.taskUid}).`,
+          return task
+        }),
       )
 
-      return task
+      return tasks.flat()
     },
 
     /**
-     * Update entries from the contentType in its index in Meilisearch.
+     * Update entries from the contentType in all its indexes in Meilisearch.
      *
      * @param  {object} options
      * @param  {string} options.contentType - ContentType name.
@@ -123,34 +131,41 @@ module.exports = ({ strapi, adapter, config }) => {
 
       if (!Array.isArray(entries)) entries = [entries]
 
-      const indexUid = config.getIndexNameOfContentType({ contentType })
-      await entries.forEach(async entry => {
-        const sanitized = await sanitizeEntries({
-          entries: [entry],
-          contentType,
-          config,
-          adapter,
-        })
-
-        if (sanitized.length === 0) {
-          const task = await client.index(indexUid).deleteDocument(
-            adapter.addCollectionNamePrefixToId({
-              contentType,
-              entryId: entry.id,
+      const indexUids = config.getIndexNamesOfContentType({ contentType })
+      await Promise.all(
+        indexUids.map(async indexUid => {
+          const tasks = await Promise.all(
+            entries.map(async entry => {
+              const sanitized = await sanitizeEntries({
+                entries: [entry],
+                contentType,
+                config,
+                adapter,
+              })
+
+              if (sanitized.length === 0) {
+                const task = await client.index(indexUid).deleteDocument(
+                  adapter.addCollectionNamePrefixToId({
+                    contentType,
+                    entryId: entry.id,
+                  }),
+                )
+
+                strapi.log.info(
+                  `A task to delete one document from the Meilisearch index "${indexUid}" has been enqueued (Task uid: ${task.taskUid}).`,
+                )
+
+                return task
+              } else {
+                return client
+                  .index(indexUid)
+                  .updateDocuments(sanitized, { primaryKey: '_meilisearch_id' })
+              }
             }),
           )
-
-          strapi.log.info(
-            `A task to delete one document from the Meilisearch index "${indexUid}" has been enqueued (Task uid: ${task.taskUid}).`,
-          )
-
-          return task
-        } else {
-          return client
-            .index(indexUid)
-            .updateDocuments(sanitized, { primaryKey: '_meilisearch_id' })
-        }
-      })
+          return tasks.flat()
+        }),
+      )
     },
 
     /**
@@ -199,58 +214,62 @@ module.exports = ({ strapi, adapter, config }) => {
       const contentTypes = contentTypeService.getContentTypesUid()
 
       const reports = await Promise.all(
-        contentTypes.map(async contentType => {
+        contentTypes.flatMap(async contentType => {
           const collectionName = contentTypeService.getCollectionName({
             contentType,
           })
-          const indexUid = config.getIndexNameOfContentType({ contentType })
-          const indexInMeiliSearch = indexUids.includes(indexUid)
-
-          const contentTypeInIndexStore =
-            indexedContentTypes.includes(contentType)
-          const indexed = indexInMeiliSearch && contentTypeInIndexStore
-
-          // safe guard in case index does not exist anymore in Meilisearch
-          if (!indexInMeiliSearch && contentTypeInIndexStore) {
-            await store.removeIndexedContentType({ contentType })
-          }
-
-          const { numberOfDocuments = 0, isIndexing = false } =
-            indexUids.includes(indexUid)
-              ? await this.getStats({ indexUid })
-              : {}
-
-          const contentTypesWithSameIndexUid =
-            await config.listContentTypesWithCustomIndexName({
-              indexName: indexUid,
-            })
-          const numberOfEntries = await contentTypeService.totalNumberOfEntries(
-            {
-              contentTypes: contentTypesWithSameIndexUid,
-            },
+          const indexUidsForContentType = config.getIndexNamesOfContentType({
+            contentType,
+          })
+          return Promise.all(
+            indexUidsForContentType.map(async indexUid => {
+              const indexInMeiliSearch = indexUids.includes(indexUid)
+              const contentTypeInIndexStore =
+                indexedContentTypes.includes(contentType)
+              const indexed = indexInMeiliSearch && contentTypeInIndexStore
+
+              // safe guard in case index does not exist anymore in Meilisearch
+              if (!indexInMeiliSearch && contentTypeInIndexStore) {
+                await store.removeIndexedContentType({ contentType })
+              }
+
+              const { numberOfDocuments = 0, isIndexing = false } =
+                indexUids.includes(indexUid)
+                  ? await this.getStats({ indexUid })
+                  : {}
+
+              const contentTypesWithSameIndexUid =
+                await config.listContentTypesWithCustomIndexName({
+                  indexName: indexUid,
+                })
+              const numberOfEntries =
+                await contentTypeService.totalNumberOfEntries({
+                  contentTypes: contentTypesWithSameIndexUid,
+                })
+              return {
+                collection: collectionName,
+                contentType: contentType,
+                indexUid,
+                indexed,
+                isIndexing,
+                numberOfDocuments,
+                numberOfEntries,
+                listened: listenedContentTypes.includes(contentType),
+              }
+            }),
           )
-          return {
-            collection: collectionName,
-            contentType: contentType,
-            indexUid,
-            indexed,
-            isIndexing,
-            numberOfDocuments,
-            numberOfEntries,
-            listened: listenedContentTypes.includes(contentType),
-          }
         }),
       )
-      return { contentTypes: reports }
+      return { contentTypes: reports.flat() }
     },
 
     /**
-     * Add entries from a contentType to its index in Meilisearch.
+     * Add entries from a contentType to all its indexes in Meilisearch.
      *
      * @param  {object} options
      * @param  {string} options.contentType - ContentType name.
      * @param  {object[] | object} options.entries - Entry from the document.
-     * @returns {Promise<{ taskUid: number }>} - Task identifier.
+     * @returns {Promise<{ taskUid: number }[]>} - Task identifiers.
      */
     addEntriesToMeilisearch: async function ({ contentType, entries }) {
       const { apiKey, host } = await store.getCredentials()
@@ -258,7 +277,7 @@ module.exports = ({ strapi, adapter, config }) => {
 
       if (!Array.isArray(entries)) entries = [entries]
 
-      const indexUid = config.getIndexNameOfContentType({ contentType })
+      const indexUids = config.getIndexNamesOfContentType({ contentType })
       const documents = await sanitizeEntries({
         contentType,
         entries,
@@ -266,21 +285,26 @@ module.exports = ({ strapi, adapter, config }) => {
         adapter,
       })
 
-      const task = await client
-        .index(indexUid)
-        .addDocuments(documents, { primaryKey: '_meilisearch_id' })
+      const tasks = await Promise.all(
+        indexUids.map(async indexUid => {
+          const task = await client
+            .index(indexUid)
+            .addDocuments(documents, { primaryKey: '_meilisearch_id' })
 
-      await store.addIndexedContentType({ contentType })
+          await store.addIndexedContentType({ contentType })
 
-      strapi.log.info(
-        `The task to add ${documents.length} documents to the Meilisearch index "${indexUid}" has been enqueued (Task uid: ${task.taskUid}).`,
+          strapi.log.info(
+            `The task to add ${documents.length} documents to the Meilisearch index "${indexUid}" has been enqueued (Task uid: ${task.taskUid}).`,
+          )
+          return task
+        }),
       )
 
-      return task
+      return tasks.flat()
     },
 
     /**
-     * Add all entries from a contentType to its index in Meilisearch.
+     * Add all entries from a contentType to all its indexes in Meilisearch.
      *
      * @param  {object} options
      * @param  {string} options.contentType - ContentType name.
@@ -290,14 +314,18 @@ module.exports = ({ strapi, adapter, config }) => {
     addContentTypeInMeiliSearch: async function ({ contentType }) {
       const { apiKey, host } = await store.getCredentials()
       const client = Meilisearch({ apiKey, host })
-      const indexUid = config.getIndexNameOfContentType({ contentType })
+      const indexUids = config.getIndexNamesOfContentType({ contentType })
 
       // Get Meilisearch Index settings from model
       const settings = config.getSettings({ contentType })
-      const task = await client.index(indexUid).updateSettings(settings)
-
-      strapi.log.info(
-        `A task to update the settings to the Meilisearch index "${indexUid}" has been enqueued (Task uid: ${task.taskUid}).`,
+      await Promise.all(
+        indexUids.map(async indexUid => {
+          const task = await client.index(indexUid).updateSettings(settings)
+          strapi.log.info(
+            `A task to update the settings to the Meilisearch index "${indexUid}" has been enqueued (Task uid: ${task.taskUid}).`,
+          )
+          return task
+        }),
       )
 
       // Callback function for batching action
@@ -311,15 +339,21 @@ module.exports = ({ strapi, adapter, config }) => {
         })
 
         // Add documents in Meilisearch
-        const { taskUid } = await client
-          .index(indexUid)
-          .addDocuments(documents, { primaryKey: '_meilisearch_id' })
-
-        strapi.log.info(
-          `A task to add ${documents.length} documents to the Meilisearch index "${indexUid}" has been enqueued (Task uid: ${taskUid}).`,
+        const taskUids = await Promise.all(
+          indexUids.map(async indexUid => {
+            const { taskUid } = await client
+              .index(indexUid)
+              .addDocuments(documents, { primaryKey: '_meilisearch_id' })
+
+            strapi.log.info(
+              `A task to add ${documents.length} documents to the Meilisearch index "${indexUid}" has been enqueued (Task uid: ${taskUid}).`,
+            )
+
+            return taskUid
+          }),
         )
 
-        return taskUid
+        return taskUids.flat()
       }
 
       const tasksUids = await contentTypeService.actionInBatches({
@@ -343,17 +377,30 @@ module.exports = ({ strapi, adapter, config }) => {
      * @returns {Promise<string[]>} - ContentTypes names.
      */
     getContentTypesWithSameIndex: async function ({ contentType }) {
-      const indexUid = config.getIndexNameOfContentType({ contentType })
+      const indexUids = config.getIndexNamesOfContentType({ contentType })
 
-      // Fetch contentTypes that has the same indexName as the provided contentType
-      const contentTypesWithSameIndex = await config
-        .listContentTypesWithCustomIndexName({ indexName: indexUid })
-        .map(contentTypeName => `api::${contentTypeName}.${contentTypeName}`)
+      // Initialize an empty array to hold contentTypes with the same index names
+      let contentTypesWithSameIndex = []
 
-      // get all contentTypes (not indexes) indexed in Meilisearch.
+      // Iterate over each indexUid to fetch and accumulate contentTypes that have the same indexName
+      for (const indexUid of indexUids) {
+        const contentTypesForCurrentIndex = await config
+          .listContentTypesWithCustomIndexName({ indexName: indexUid })
+          .map(contentTypeName => `api::${contentTypeName}.${contentTypeName}`)
+
+        contentTypesWithSameIndex = [
+          ...contentTypesWithSameIndex,
+          ...contentTypesForCurrentIndex,
+        ]
+      }
+
+      // Remove duplicates
+      contentTypesWithSameIndex = [...new Set(contentTypesWithSameIndex)]
+
+      // Get all contentTypes (not indexes) indexed in Meilisearch.
       const indexedContentTypes = await store.getIndexedContentTypes()
 
-      // Take union of both array
+      // Take intersection of both arrays
       const indexedContentTypesWithSameIndex = indexedContentTypes.filter(
         contentType => contentTypesWithSameIndex.includes(contentType),
       )
@@ -362,7 +409,7 @@ module.exports = ({ strapi, adapter, config }) => {
     },
 
     /**
-     * Delete or empty an index depending if the contentType is part
+     * Delete or empty all indexes of a contentType, depending if the contentType is part
      * of a composite index.
      *
      * @param  {object} options
@@ -389,11 +436,15 @@ module.exports = ({ strapi, adapter, config }) => {
         const { apiKey, host } = await store.getCredentials()
         const client = Meilisearch({ apiKey, host })
 
-        const indexUid = config.getIndexNameOfContentType({ contentType })
-        const { taskUid } = await client.index(indexUid).delete()
-
-        strapi.log.info(
-          `A task to delete the Meilisearch index "${indexUid}" has been added to the queue (Task uid: ${taskUid}).`,
+        const indexUids = config.getIndexNamesOfContentType({ contentType })
+        await Promise.all(
+          indexUids.map(async indexUid => {
+            const { taskUid } = await client.index(indexUid).delete()
+            strapi.log.info(
+              `A task to delete the Meilisearch index "${indexUid}" has been added to the queue (Task uid: ${taskUid}).`,
+            )
+            return taskUid
+          }),
         )
       }
 


Test patch:
diff --git a/server/__tests__/configuration-validation.test.js b/server/__tests__/configuration-validation.test.js
index 0515586..ad10670 100644
--- a/server/__tests__/configuration-validation.test.js
+++ b/server/__tests__/configuration-validation.test.js
@@ -122,14 +122,50 @@ describe('Test plugin configuration', () => {
     expect(strapiMock.log.warn).toHaveBeenCalledTimes(0)
     expect(strapiMock.log.error).toHaveBeenCalledTimes(1)
     expect(strapiMock.log.error).toHaveBeenCalledWith(
-      'The "indexName" option of "restaurant" should be a non-empty string',
+      'The "indexName" option of "restaurant" should be a non-empty string or an array of non-empty strings',
     )
   })
 
   test('Test indexName with non-empty string', async () => {
     validatePluginConfig({
       restaurant: {
-        indexName: 'hello',
+        indexName: 'validName',
+      },
+    })
+    expect(strapiMock.log.warn).toHaveBeenCalledTimes(0)
+    expect(strapiMock.log.error).toHaveBeenCalledTimes(0)
+  })
+
+  test('Test indexName with empty array', async () => {
+    validatePluginConfig({
+      restaurant: {
+        indexName: [],
+      },
+    })
+    expect(strapiMock.log.warn).toHaveBeenCalledTimes(0)
+    expect(strapiMock.log.error).toHaveBeenCalledTimes(1)
+    expect(strapiMock.log.error).toHaveBeenCalledWith(
+      'The "indexName" option of "restaurant" should be a non-empty string or an array of non-empty strings',
+    )
+  })
+
+  test('Test indexName with non-empty array containing empty string', async () => {
+    validatePluginConfig({
+      restaurant: {
+        indexName: [''],
+      },
+    })
+    expect(strapiMock.log.warn).toHaveBeenCalledTimes(0)
+    expect(strapiMock.log.error).toHaveBeenCalledTimes(1)
+    expect(strapiMock.log.error).toHaveBeenCalledWith(
+      'The "indexName" option of "restaurant" should be a non-empty string or an array of non-empty strings',
+    )
+  })
+
+  test('Test indexName with non-empty array of strings', async () => {
+    validatePluginConfig({
+      restaurant: {
+        indexName: ['validName1', 'validName2'],
       },
     })
     expect(strapiMock.log.warn).toHaveBeenCalledTimes(0)
diff --git a/server/__tests__/configuration.test.js b/server/__tests__/configuration.test.js
index fc19ca8..c34a8ea 100644
--- a/server/__tests__/configuration.test.js
+++ b/server/__tests__/configuration.test.js
@@ -20,7 +20,7 @@ describe('Test Meilisearch plugin configurations', () => {
       strapi: customStrapi,
     })
 
-    const indexName = meilisearchService.getIndexNameOfContentType({
+    const indexNames = meilisearchService.getIndexNamesOfContentType({
       contentType,
     })
     const entries = await meilisearchService.transformEntries({
@@ -31,7 +31,7 @@ describe('Test Meilisearch plugin configurations', () => {
       contentType,
     })
 
-    expect(indexName).toEqual(contentType)
+    expect(indexNames).toEqual([contentType])
     expect(entries).toEqual([{ id: 1 }])
     expect(settings).toEqual({})
   })
@@ -45,7 +45,7 @@ describe('Test Meilisearch plugin configurations', () => {
     const meilisearchService = createMeilisearchService({
       strapi: customStrapi,
     })
-    const indexName = meilisearchService.getIndexNameOfContentType({
+    const indexNames = meilisearchService.getIndexNamesOfContentType({
       contentType,
     })
     const entries = await meilisearchService.transformEntries({
@@ -56,7 +56,7 @@ describe('Test Meilisearch plugin configurations', () => {
       contentType,
     })
 
-    expect(indexName).toEqual(contentType)
+    expect(indexNames).toEqual([contentType])
     expect(entries).toEqual([{ id: 1 }])
     expect(settings).toEqual({})
   })
@@ -70,7 +70,7 @@ describe('Test Meilisearch plugin configurations', () => {
     const meilisearchService = createMeilisearchService({
       strapi: customStrapi,
     })
-    const indexName = meilisearchService.getIndexNameOfContentType({
+    const indexNames = meilisearchService.getIndexNamesOfContentType({
       contentType,
     })
     const entries = await meilisearchService.transformEntries({
@@ -81,7 +81,7 @@ describe('Test Meilisearch plugin configurations', () => {
       contentType,
     })
 
-    expect(indexName).toEqual(contentType)
+    expect(indexNames).toEqual([contentType])
     expect(entries).toEqual([{ id: 1 }])
     expect(settings).toEqual({})
   })
@@ -91,11 +91,11 @@ describe('Test Meilisearch plugin configurations', () => {
       restaurantConfig: {},
     })
 
-    const contentType = 'customName'
+    const contentType = 'restaurant'
     const meilisearchService = createMeilisearchService({
       strapi: customStrapi,
     })
-    const indexName = meilisearchService.getIndexNameOfContentType({
+    const indexNames = meilisearchService.getIndexNamesOfContentType({
       contentType,
     })
 
@@ -107,23 +107,83 @@ describe('Test Meilisearch plugin configurations', () => {
       contentType,
     })
 
-    expect(indexName).toEqual(contentType)
+    expect(indexNames).toEqual([contentType])
     expect(entries).toEqual([{ id: 1 }])
     expect(settings).toEqual({})
   })
 
   test('Test configuration with non-empty type indexName', async () => {
+    const customIndexName = 'customName'
+    const customStrapi = createStrapiMock({
+      restaurantConfig: {
+        indexName: [customIndexName],
+      },
+    })
+
+    const contentType = 'restaurant'
+    const meilisearchService = createMeilisearchService({
+      strapi: customStrapi,
+    })
+    const indexNames = meilisearchService.getIndexNamesOfContentType({
+      contentType,
+    })
+
+    const entries = await meilisearchService.transformEntries({
+      contentType,
+      entries: [{ id: 1 }],
+    })
+    const settings = meilisearchService.getSettings({
+      contentType,
+    })
+
+    expect(indexNames).toEqual([customIndexName])
+    expect(entries).toEqual([{ id: 1 }])
+    expect(settings).toEqual({})
+  })
+
+  test('Test configuration with non-empty and several indexName', async () => {
+    const customIndexName = 'customName'
+    const customIndexName2 = 'otherCustomName'
+    const customStrapi = createStrapiMock({
+      restaurantConfig: {
+        indexName: [customIndexName, customIndexName2],
+      },
+    })
+
+    const contentType = 'restaurant'
+    const meilisearchService = createMeilisearchService({
+      strapi: customStrapi,
+    })
+    const indexNames = meilisearchService.getIndexNamesOfContentType({
+      contentType,
+    })
+
+    const entries = await meilisearchService.transformEntries({
+      contentType,
+      entries: [{ id: 1 }],
+    })
+    const settings = meilisearchService.getSettings({
+      contentType,
+    })
+
+    expect(indexNames).toEqual([customIndexName, customIndexName2])
+    expect(entries).toEqual([{ id: 1 }])
+    expect(settings).toEqual({})
+  })
+
+  test('Test configuration with indexName that is not an array', async () => {
+    const customIndexName = 'customName'
     const customStrapi = createStrapiMock({
       restaurantConfig: {
-        indexName: 'customName',
+        indexName: customIndexName,
       },
     })
 
-    const contentType = 'customName'
+    const contentType = 'restaurant'
     const meilisearchService = createMeilisearchService({
       strapi: customStrapi,
     })
-    const indexName = meilisearchService.getIndexNameOfContentType({
+    const indexNames = meilisearchService.getIndexNamesOfContentType({
       contentType,
     })
 
@@ -135,7 +195,7 @@ describe('Test Meilisearch plugin configurations', () => {
       contentType,
     })
 
-    expect(indexName).toEqual(contentType)
+    expect(indexNames).toEqual([customIndexName])
     expect(entries).toEqual([{ id: 1 }])
     expect(settings).toEqual({})
   })
@@ -151,7 +211,7 @@ describe('Test Meilisearch plugin configurations', () => {
     const meilisearchService = createMeilisearchService({
       strapi: customStrapi,
     })
-    const indexName = meilisearchService.getIndexNameOfContentType({
+    const indexNames = meilisearchService.getIndexNamesOfContentType({
       contentType,
     })
     const entries = await meilisearchService.transformEntries({
@@ -162,7 +222,7 @@ describe('Test Meilisearch plugin configurations', () => {
       contentType,
     })
 
-    expect(indexName).toEqual(contentType)
+    expect(indexNames).toEqual([contentType])
     expect(entries).toEqual([{ id: 1 }])
     expect(settings).toEqual({})
   })
@@ -183,7 +243,7 @@ describe('Test Meilisearch plugin configurations', () => {
     const meilisearchService = createMeilisearchService({
       strapi: customStrapi,
     })
-    const indexName = meilisearchService.getIndexNameOfContentType({
+    const indexNames = meilisearchService.getIndexNamesOfContentType({
       contentType,
     })
     const entries = await meilisearchService.transformEntries({
@@ -194,7 +254,7 @@ describe('Test Meilisearch plugin configurations', () => {
       contentType,
     })
 
-    expect(indexName).toEqual(contentType)
+    expect(indexNames).toEqual([contentType])
     expect(entries).toEqual([
       { id: 1, name: 'hello' },
       { id: 2, name: 'hello' },
@@ -215,7 +275,7 @@ describe('Test Meilisearch plugin configurations', () => {
     const meilisearchService = createMeilisearchService({
       strapi: customStrapi,
     })
-    const indexName = meilisearchService.getIndexNameOfContentType({
+    const indexNames = meilisearchService.getIndexNamesOfContentType({
       contentType,
     })
     const entries = await meilisearchService.filterEntries({
@@ -230,7 +290,7 @@ describe('Test Meilisearch plugin configurations', () => {
       contentType,
     })
 
-    expect(indexName).toEqual(contentType)
+    expect(indexNames).toEqual([contentType])
     expect(entries).toEqual([{ id: 2, name: 'two' }])
     expect(settings).toEqual({})
   })
@@ -248,7 +308,7 @@ describe('Test Meilisearch plugin configurations', () => {
     const meilisearchService = createMeilisearchService({
       strapi: customStrapi,
     })
-    const indexName = meilisearchService.getIndexNameOfContentType({
+    const indexNames = meilisearchService.getIndexNamesOfContentType({
       contentType,
     })
     const entries = await meilisearchService.transformEntries({
@@ -259,7 +319,7 @@ describe('Test Meilisearch plugin configurations', () => {
       contentType,
     })
 
-    expect(indexName).toEqual(contentType)
+    expect(indexNames).toEqual([contentType])
     expect(entries).toEqual([])
     expect(settings).toEqual({})
   })
@@ -275,7 +335,7 @@ describe('Test Meilisearch plugin configurations', () => {
     const meilisearchService = createMeilisearchService({
       strapi: customStrapi,
     })
-    const indexName = meilisearchService.getIndexNameOfContentType({
+    const indexNames = meilisearchService.getIndexNamesOfContentType({
       contentType,
     })
     const entries = await meilisearchService.transformEntries({
@@ -286,7 +346,7 @@ describe('Test Meilisearch plugin configurations', () => {
       contentType,
     })
 
-    expect(indexName).toEqual(contentType)
+    expect(indexNames).toEqual([contentType])
     expect(entries).toEqual([])
     expect(settings).toEqual({})
   })
@@ -347,7 +407,7 @@ describe('Test Meilisearch plugin configurations', () => {
     const meilisearchService = createMeilisearchService({
       strapi: customStrapi,
     })
-    const indexName = meilisearchService.getIndexNameOfContentType({
+    const indexNames = meilisearchService.getIndexNamesOfContentType({
       contentType,
     })
     const entries = meilisearchService.removeUnpublishedArticles({
@@ -358,7 +418,7 @@ describe('Test Meilisearch plugin configurations', () => {
       ],
     })
 
-    expect(indexName).toEqual(contentType)
+    expect(indexNames).toEqual([contentType])
     expect(entries).toEqual([
       { id: 1, publishedAt: null },
       { id: 2, publishedAt: null },
@@ -376,7 +436,7 @@ describe('Test Meilisearch plugin configurations', () => {
     const meilisearchService = createMeilisearchService({
       strapi: customStrapi,
     })
-    const indexName = meilisearchService.getIndexNameOfContentType({
+    const indexNames = meilisearchService.getIndexNamesOfContentType({
       contentType,
     })
     const entries = await meilisearchService.transformEntries({
@@ -387,7 +447,7 @@ describe('Test Meilisearch plugin configurations', () => {
       contentType,
     })
 
-    expect(indexName).toEqual(contentType)
+    expect(indexNames).toEqual([contentType])
     expect(entries).toEqual([{ id: 1 }, { id: 2 }])
     expect(settings).toEqual({})
   })
@@ -403,7 +463,7 @@ describe('Test Meilisearch plugin configurations', () => {
     const meilisearchService = createMeilisearchService({
       strapi: customStrapi,
     })
-    const indexName = meilisearchService.getIndexNameOfContentType({
+    const indexNames = meilisearchService.getIndexNamesOfContentType({
       contentType,
     })
     const entries = await meilisearchService.transformEntries({
@@ -414,7 +474,7 @@ describe('Test Meilisearch plugin configurations', () => {
       contentType,
     })
 
-    expect(indexName).toEqual(contentType)
+    expect(indexNames).toEqual([contentType])
     expect(entries).toEqual([{ id: 1 }, { id: 2 }])
     expect(settings).toEqual({})
   })
@@ -432,7 +492,7 @@ describe('Test Meilisearch plugin configurations', () => {
     const meilisearchService = createMeilisearchService({
       strapi: customStrapi,
     })
-    const indexName = meilisearchService.getIndexNameOfContentType({
+    const indexNames = meilisearchService.getIndexNamesOfContentType({
       contentType,
     })
     const entries = await meilisearchService.transformEntries({
@@ -443,7 +503,7 @@ describe('Test Meilisearch plugin configurations', () => {
       contentType,
     })
 
-    expect(indexName).toEqual(contentType)
+    expect(indexNames).toEqual([contentType])
     expect(entries).toEqual([{ id: 1 }, { id: 2 }])
     expect(settings).toEqual({
       mySettings: 'hello',
@@ -453,11 +513,34 @@ describe('Test Meilisearch plugin configurations', () => {
   test('Test all contentTypes pointing to the same custom index name', async () => {
     const customStrapi = createStrapiMock({
       restaurantConfig: {
-        indexName: 'my_index',
+        indexName: ['my_index'],
       },
       aboutConfig: {
+        indexName: ['my_index'],
+      },
+    })
+
+    const meilisearchService = createMeilisearchService({
+      strapi: customStrapi,
+    })
+
+    const contentTypes = meilisearchService.listContentTypesWithCustomIndexName(
+      {
         indexName: 'my_index',
       },
+    )
+
+    expect(contentTypes).toEqual(['restaurant', 'about'])
+  })
+
+  test('Test all contentTypes pointing to the same custom index name, with multiple index names', async () => {
+    const customStrapi = createStrapiMock({
+      restaurantConfig: {
+        indexName: ['another_index', 'my_index'],
+      },
+      aboutConfig: {
+        indexName: ['my_index', 'another_index2'],
+      },
     })
 
     const meilisearchService = createMeilisearchService({
diff --git a/server/__tests__/meilisearch.test.js b/server/__tests__/meilisearch.test.js
index d32beb5..737054b 100644
--- a/server/__tests__/meilisearch.test.js
+++ b/server/__tests__/meilisearch.test.js
@@ -28,10 +28,184 @@ describe('Tests content types', () => {
     expect(indexes).toEqual(['my_restaurant', 'restaurant'])
   })
 
+  test('Test to add entries in Meilisearch', async () => {
+    const pluginMock = jest.fn(() => ({
+      // This rewrites only the needed methods to reach the system under test (removeSensitiveFields)
+      service: jest.fn().mockImplementation(() => {
+        return {
+          async actionInBatches({ contentType = 'restaurant', callback }) {
+            await callback({
+              entries: [
+                {
+                  id: 1,
+                  title: 'title',
+                  internal_notes: 'note123',
+                  secret: '123',
+                },
+                {
+                  id: 2,
+                  title: 'abc',
+                  internal_notes: 'note234',
+                  secret: '234',
+                },
+              ],
+              contentType,
+            })
+          },
+          getCollectionName: ({ contentType }) => contentType,
+          addIndexedContentType: jest.fn(),
+          subscribeContentType: jest.fn(),
+          getCredentials: () => ({}),
+        }
+      }),
+    }))
+
+    // Spy
+    const client = new Meilisearch({ host: 'abc' })
+
+    const meilisearchService = createMeilisearchService({
+      strapi: {
+        plugin: pluginMock,
+        contentTypes: {
+          restaurant: {
+            attributes: {
+              id: { private: false },
+              title: { private: false },
+              internal_notes: { private: true },
+              secret: { private: true },
+            },
+          },
+        },
+        config: {
+          get: jest.fn(() => ({
+            restaurant: {
+              noSanitizePrivateFields: ['internal_notes'],
+              indexName: 'customIndex',
+            },
+          })),
+        },
+        log: mockLogger,
+      },
+      contentTypes: {
+        restaurant: {
+          attributes: {
+            id: { private: false },
+            title: { private: false },
+            internal_notes: { private: true },
+            secret: { private: true },
+          },
+        },
+      },
+    })
+
+    const mockEntry = { attributes: { id: 1 } }
+    const tasks = await meilisearchService.addEntriesToMeilisearch({
+      contentType: 'restaurant',
+      entries: [mockEntry, mockEntry],
+    })
+
+    expect(strapi.log.info).toHaveBeenCalledTimes(1)
+    expect(strapi.log.info).toHaveBeenCalledWith(
+      'The task to add 2 documents to the Meilisearch index "customIndex" has been enqueued (Task uid: undefined).',
+    )
+    expect(client.index('').addDocuments).toHaveBeenCalledTimes(1)
+    expect(client.index).toHaveBeenCalledWith('customIndex')
+    expect(tasks).toEqual([10])
+  })
+
+  test('Test to add entries linked to multiple indexes in Meilisearch', async () => {
+    const pluginMock = jest.fn(() => ({
+      // This rewrites only the needed methods to reach the system under test (removeSensitiveFields)
+      service: jest.fn().mockImplementation(() => {
+        return {
+          async actionInBatches({ contentType = 'restaurant', callback }) {
+            await callback({
+              entries: [
+                {
+                  id: 1,
+                  title: 'title',
+                  internal_notes: 'note123',
+                  secret: '123',
+                },
+                {
+                  id: 2,
+                  title: 'abc',
+                  internal_notes: 'note234',
+                  secret: '234',
+                },
+              ],
+              contentType,
+            })
+          },
+          getCollectionName: ({ contentType }) => contentType,
+          addIndexedContentType: jest.fn(),
+          subscribeContentType: jest.fn(),
+          getCredentials: () => ({}),
+        }
+      }),
+    }))
+
+    // Spy
+    const client = new Meilisearch({ host: 'abc' })
+
+    const meilisearchService = createMeilisearchService({
+      strapi: {
+        plugin: pluginMock,
+        contentTypes: {
+          restaurant: {
+            attributes: {
+              id: { private: false },
+              title: { private: false },
+              internal_notes: { private: true },
+              secret: { private: true },
+            },
+          },
+        },
+        config: {
+          get: jest.fn(() => ({
+            restaurant: {
+              noSanitizePrivateFields: ['internal_notes'],
+              indexName: ['customIndex', 'anotherIndex'],
+            },
+          })),
+        },
+        log: mockLogger,
+      },
+      contentTypes: {
+        restaurant: {
+          attributes: {
+            id: { private: false },
+            title: { private: false },
+            internal_notes: { private: true },
+            secret: { private: true },
+          },
+        },
+      },
+    })
+
+    const mockEntry = { attributes: { id: 1 } }
+    const tasks = await meilisearchService.addEntriesToMeilisearch({
+      contentType: 'restaurant',
+      entries: [mockEntry, mockEntry],
+    })
+
+    expect(strapi.log.info).toHaveBeenCalledTimes(2)
+    expect(strapi.log.info).toHaveBeenCalledWith(
+      'The task to add 2 documents to the Meilisearch index "customIndex" has been enqueued (Task uid: undefined).',
+    )
+    expect(strapi.log.info).toHaveBeenCalledWith(
+      'The task to add 2 documents to the Meilisearch index "anotherIndex" has been enqueued (Task uid: undefined).',
+    )
+    expect(client.index('').addDocuments).toHaveBeenCalledTimes(2)
+    expect(client.index).toHaveBeenCalledWith('customIndex')
+    expect(client.index).toHaveBeenCalledWith('anotherIndex')
+    expect(tasks).toEqual([10, 10])
+  })
+
   test('Test to delete entries from Meilisearch', async () => {
     const customStrapi = createStrapiMock({
       restaurantConfig: {
-        indexName: 'customIndex',
+        indexName: ['customIndex'],
       },
     })
 
@@ -60,6 +234,47 @@ describe('Tests content types', () => {
     expect(tasks).toEqual([{ taskUid: 1 }, { taskUid: 2 }])
   })
 
+  test('Test to delete entries linked to multiple indexes from Meilisearch', async () => {
+    const customStrapi = createStrapiMock({
+      restaurantConfig: {
+        indexName: ['customIndex', 'anotherIndex'],
+      },
+    })
+
+    // Spy
+    const client = new Meilisearch({ host: 'abc' })
+
+    const meilisearchService = createMeilisearchService({
+      strapi: customStrapi,
+    })
+
+    const tasks = await meilisearchService.deleteEntriesFromMeiliSearch({
+      contentType: 'restaurant',
+      entriesId: [1, 2],
+    })
+
+    expect(customStrapi.log.info).toHaveBeenCalledTimes(2)
+    expect(customStrapi.log.info).toHaveBeenCalledWith(
+      'A task to delete 2 documents of the index "customIndex" in Meilisearch has been enqueued (Task uid: undefined).',
+    )
+    expect(customStrapi.log.info).toHaveBeenCalledWith(
+      'A task to delete 2 documents of the index "anotherIndex" in Meilisearch has been enqueued (Task uid: undefined).',
+    )
+    expect(client.index('').deleteDocuments).toHaveBeenCalledTimes(2)
+    expect(client.index('').deleteDocuments).toHaveBeenCalledWith([
+      'restaurant-1',
+      'restaurant-2',
+    ])
+    expect(client.index).toHaveBeenCalledWith('customIndex')
+    expect(client.index).toHaveBeenCalledWith('anotherIndex')
+    expect(tasks).toEqual([
+      { taskUid: 1 },
+      { taskUid: 2 },
+      { taskUid: 1 },
+      { taskUid: 2 },
+    ])
+  })
+
   test('Test to get stats', async () => {
     const customStrapi = createStrapiMock({})
 
@@ -119,6 +334,138 @@ describe('Tests content types', () => {
     )
   })
 
+  test('Test to update the content of a collection in Meilisearch with a custom index name', async () => {
+    const customStrapi = createStrapiMock({
+      restaurantConfig: {
+        indexName: ['customIndex'],
+        entriesQuery: {
+          limit: 1,
+          fields: ['id'],
+          filters: {},
+          sort: {},
+          populate: [],
+          publicationState: 'preview',
+        },
+      },
+    })
+
+    const meilisearchService = createMeilisearchService({
+      strapi: customStrapi,
+    })
+
+    await meilisearchService.addContentTypeInMeiliSearch({
+      contentType: 'restaurant',
+    })
+
+    expect(
+      customStrapi.plugin().service().actionInBatches,
+    ).toHaveBeenCalledWith({
+      contentType: 'restaurant',
+      callback: expect.anything(),
+      entriesQuery: {
+        limit: 1,
+        fields: ['id'],
+        filters: {},
+        sort: {},
+        populate: [],
+        publicationState: 'preview',
+      },
+    })
+    expect(customStrapi.log.info).toHaveBeenCalledTimes(1)
+    expect(customStrapi.log.info).toHaveBeenCalledWith(
+      'A task to update the settings to the Meilisearch index "customIndex" has been enqueued (Task uid: undefined).',
+    )
+  })
+
+  test('Test to update the content of a collection in Meilisearch with a multiple index names', async () => {
+    const customStrapi = createStrapiMock({
+      restaurantConfig: {
+        indexName: ['customIndex', 'anotherIndex'],
+        entriesQuery: {
+          limit: 1,
+          fields: ['id'],
+          filters: {},
+          sort: {},
+          populate: [],
+          publicationState: 'preview',
+        },
+      },
+    })
+
+    const meilisearchService = createMeilisearchService({
+      strapi: customStrapi,
+    })
+
+    await meilisearchService.addContentTypeInMeiliSearch({
+      contentType: 'restaurant',
+    })
+
+    expect(
+      customStrapi.plugin().service().actionInBatches,
+    ).toHaveBeenCalledWith({
+      contentType: 'restaurant',
+      callback: expect.anything(),
+      entriesQuery: {
+        limit: 1,
+        fields: ['id'],
+        filters: {},
+        sort: {},
+        populate: [],
+        publicationState: 'preview',
+      },
+    })
+    expect(customStrapi.log.info).toHaveBeenCalledTimes(2)
+    expect(customStrapi.log.info).toHaveBeenCalledWith(
+      'A task to update the settings to the Meilisearch index "customIndex" has been enqueued (Task uid: undefined).',
+    )
+    expect(customStrapi.log.info).toHaveBeenCalledWith(
+      'A task to update the settings to the Meilisearch index "anotherIndex" has been enqueued (Task uid: undefined).',
+    )
+  })
+
+  test('Test to update the content of a collection in Meilisearch with a custom index name', async () => {
+    const customStrapi = createStrapiMock({
+      restaurantConfig: {
+        indexName: 'customIndex',
+        entriesQuery: {
+          limit: 1,
+          fields: ['id'],
+          filters: {},
+          sort: {},
+          populate: [],
+          publicationState: 'preview',
+        },
+      },
+    })
+
+    const meilisearchService = createMeilisearchService({
+      strapi: customStrapi,
+    })
+
+    await meilisearchService.addContentTypeInMeiliSearch({
+      contentType: 'restaurant',
+    })
+
+    expect(
+      customStrapi.plugin().service().actionInBatches,
+    ).toHaveBeenCalledWith({
+      contentType: 'restaurant',
+      callback: expect.anything(),
+      entriesQuery: {
+        limit: 1,
+        fields: ['id'],
+        filters: {},
+        sort: {},
+        populate: [],
+        publicationState: 'preview',
+      },
+    })
+    expect(customStrapi.log.info).toHaveBeenCalledTimes(1)
+    expect(customStrapi.log.info).toHaveBeenCalledWith(
+      'A task to update the settings to the Meilisearch index "customIndex" has been enqueued (Task uid: undefined).',
+    )
+  })
+
   test('selectively sanitizes the private fields from the entries', async () => {
     const pluginMock = jest.fn(() => ({
       // This rewrites only the needed methods to reach the system under test (removeSensitiveFields)
@@ -198,4 +545,67 @@ describe('Tests content types', () => {
       { primaryKey: '_meilisearch_id' },
     )
   })
+
+  test('Test to get content types with same index', async () => {
+    const customStrapi = createStrapiMock({
+      restaurantConfig: {
+        indexName: 'customIndex',
+      },
+      aboutConfig: {
+        indexName: 'customIndex',
+      },
+    })
+
+    const meilisearchService = createMeilisearchService({
+      strapi: customStrapi,
+    })
+
+    const result = await meilisearchService.getContentTypesWithSameIndex({
+      contentType: 'restaurant',
+    })
+
+    expect(result).toEqual(['api::restaurant.restaurant', 'api::about.about'])
+  })
+
+  test('Test to get content types with same index', async () => {
+    const customStrapi = createStrapiMock({
+      restaurantConfig: {
+        indexName: 'customIndex',
+      },
+      aboutConfig: {
+        indexName: 'anotherIndex',
+      },
+    })
+
+    const meilisearchService = createMeilisearchService({
+      strapi: customStrapi,
+    })
+
+    const result = await meilisearchService.getContentTypesWithSameIndex({
+      contentType: 'restaurant',
+    })
+
+    expect(result).toEqual(['api::restaurant.restaurant'])
+  })
+
+  test('Test to get content types with same index, edge case with multiple indexes', async () => {
+    const customStrapi = createStrapiMock({
+      restaurantConfig: {
+        indexName: ['customIndex'],
+      },
+      aboutConfig: {
+        indexName: ['customIndex', 'anotherIndex'],
+      },
+    })
+
+    const meilisearchService = createMeilisearchService({
+      strapi: customStrapi,
+    })
+
+    const result = await meilisearchService.getContentTypesWithSameIndex({
+      contentType: 'restaurant',
+    })
+
+    expect(result).toEqual(['api::restaurant.restaurant', 'api::about.about'])
+  })
 })