Coder Social home page Coder Social logo

meilisearch / strapi-plugin-meilisearch Goto Github PK

View Code? Open in Web Editor NEW
212.0 7.0 51.0 9.89 MB

A strapi plugin to add your collections to Meilisearch

Home Page: https://meilisearch.com

License: MIT License

JavaScript 99.03% HTML 0.87% Dockerfile 0.10%
strapi plugin search meilisearch strapi-plugin

strapi-plugin-meilisearch's Introduction

Meilisearch-Strapi

Meilisearch Strapi Plugin

npm version Tests Prettier License Bors enabled

⚑ The Meilisearch plugin for Strapi

Meilisearch is an open-source search engine. Discover what Meilisearch is!

Add your Strapi content-types into a Meilisearch instance. The plugin listens to modifications made on your content-types and updates Meilisearch accordingly.

Table of Contents

πŸ“– Documentation

To understand Meilisearch and how it works, see the Meilisearch's documentation.

To understand Strapi and how to create an app, see Strapi's documentation.

⚑ Supercharge your Meilisearch experience

Say goodbye to server deployment and manual updates with Meilisearch Cloud. Get started with a 14-day free trial! No credit card required.

πŸ”§ Installation

This package version works with the v4 of Strapi. If you are using Strapi v3, please refer to this README.

Inside your Strapi app, add the package:

With npm:

npm install strapi-plugin-meilisearch

With yarn:

yarn add strapi-plugin-meilisearch

To apply the plugin to Strapi, a re-build is needed:

strapi build

You will need both a running Strapi app and a running Meilisearch instance. For specific version compatibility see this section.

πŸƒβ€β™€οΈ Run Meilisearch

There are many easy ways to download and run a Meilisearch instance.

For example, if you use Docker:

docker pull getmeili/meilisearch:latest # Fetch the latest version of Meilisearch image from Docker Hub
docker run -it --rm -p 7700:7700 getmeili/meilisearch:latest meilisearch --master-key=masterKey

πŸƒβ€β™‚οΈ Run Strapi

If you don't have a running Strapi project yet, you can either launch the playground present in this project or create a Strapi project.

We recommend indexing your content-types to Meilisearch in development mode to allow the server reloads needed to apply or remove listeners.

strapi develop
// or
yarn develop

Run Both with Docker

To run Meilisearch and Strapi on the same server you can use Docker. A Docker configuration example can be found in the directory resources/docker of this repository.

To run the Docker script add both files Dockerfile and docker-compose.yaml at the root of your Strapi project and run it with the following command: docker-compose up.

🎬 Getting Started

Now that you have installed the plugin, a running Meilisearch instance and, a running Strapi app, let's go to the plugin page on your admin dashboard.

On the left-navbar, Meilisearch appears under the PLUGINS category. If it does not, ensure that you have installed the plugin and re-build Strapi (see installation).

🀫 Add Credentials

First, you need to configure credentials via the Strapi config, or on the plugin page. The credentials are composed of:

  • The host: The url to your running Meilisearch instance.
  • The api_key: The master or private key as the plugin requires administration permission on Meilisearch.More about permissions here.

⚠️ The master or private key should never be used to search on your front end. For searching, use the public key available on the key route.

Using the plugin page

You can add your Meilisearch credentials in the settings tab on the Meilisearch plugin page.

For example, using the credentials from the section above: Run Meilisearch, the following screen shows where the information should be.

Add your credentials

Once completed, click on the add button.

Using a config file

To use the Strapi config add the following to config/plugins.js:

// config/plugins.js

module.exports = () => ({
  //...
  meilisearch: {
    config: {
      // Your meili host
      host: "http://localhost:7700",
      // Your master key or private key
      apiKey: "masterKey",
    }
  }
})

Note that if you use both methods, the config file overwrites the credentials added through the plugin page.

πŸš› Add your content-types to Meilisearch

If you don't have any content-types yet in your Strapi Plugin, please follow Strapi quickstart.

We will use, as example, the content-types provided by Strapi's quickstart (plus the user content-type).

On your plugin homepage, you should have two content-types appearing: restaurant, category and user.

Content-types

By clicking on the left checkbox, the content-type is automatically indexed in Meilisearch. For example, if you click on the restaurant checkbox, the indexing to Meilisearch starts.

Content-types

Once the indexing is done, your restaurants are in Meilisearch. We will see in start searching how to try it out.

πŸͺ Apply Hooks

Hooks are listeners that update Meilisearch each time you add/update/delete an entry in your content-types. They are activated as soon as you add a content-type to Meilisearch. For example by clicking on the checkbox of restaurant.

Nonetheless, if you remove a content-type from Meilisearch by unchecking the checkbox, you need to reload the server. If you don't, actions are still listened to and applied to Meilisearch. The reload is only possible in develop mode; click on the Reload Server button. If not, reload the server manually!

Remove hook from content-type

πŸ’… Customization

It is possible to add settings for every collection. Start by creating a sub-object with the name of the collection inside your plugins.js file.

// config/plugins.js

module.exports = () => ({
  //...
  meilisearch: {
    config: {
      restaurant: {}
    }
  }
})

Settings:

🏷 Custom index name

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:

In the following example, the restaurant content-type in Meilisearch is called my_restaurant instead of the default restaurant.

// 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:

// config/plugins.js

module.exports = () => ({
  //...
  meilisearch: {
    config: {
      shirts: {
        indexName: 'products',
      },
      shoes: {
        indexName: 'products',
      },
    },
  },
})

Now, on each entry addition from both shoes and shirts the entry is added in the product index of Meilisearch.

disclaimer

Nonetheless, it is not possible to know how many entries from each content-type is added to Meilisearch.

For example, given two content-types:

  • Shoes: with 300 entries and an indexName set to product
  • Shirts: 200 entries and an indexName set to product

The index product has both the entries of shoes and shirts. If the index product has 350 documents in Meilisearch, it is not possible to know how many of them are from shoes or shirts.

When removing shoes or shirts from Meilisearch, both are removed as it would require to much processing to only remove one. You can still re-index only one after that.

Example with two single types:

Example of two content-types with same indexName

Examples can be found this directory.

πŸͺ„ Transform entries

By default, the plugin sent the data the way it is stored in your Strapi content-type. It is possible to remove or transform fields before sending your entries to Meilisearch.

Create the alteration function transformEntry in the plugin's configuration file. Before sending the data to Meilisearch, every entry passes through this function where the alteration is applied.

transformEntry can be synchronous or asynchronous.

You can find a lot of examples in this directory.

Example

For example, the restaurant content-type has a relation with the category content-type. Inside a restaurant entry the categories field contains an array of each category in an object format: [{ name: "Brunch" ...}, { name: "Italian ... }].

The following transforms categories in an array of strings containing only the name of the category:

// config/plugins.js

module.exports = {
  meilisearch: {
    config: {
      restaurant: {
        transformEntry({ entry }) { // can also be async
          return {
            ...entry,
            categories: entry.categories.map(category => category.name)
          }
        },
      }
    }
  },
}

Result:

  {
    "id": 2,
    "name": "Squared Pizza",
    "categories": [
      "Brunch",
      "Italian"
    ],
    // other fields
  }

By transforming the categories into an array of names, it is now compatible with the filtering feature in Meilisearch.

Important: You should always return the id of the entry without any transformation to allow sync when unpublished or deleting some entries in Strapi.

🀚 Filter entries

You might want to filter out some entries. This is possible with the filterEntry. Imagine you don't like Alfredo's restaurant. You can filter out this specific entry.

filterEntry can be synchronous or asynchronous.

// config/plugins.js

module.exports = {
  meilisearch: {
    config: {
      restaurant: {
        filterEntry({ entry }) { // can also be async
          return entry.title !== `Alfredo`
        },
      },
    },
  },
}

Alfredo's restaurant is not added to Meilisearch.

πŸ— Add Meilisearch settings

Each index in Meilisearch can be customized with specific settings. It is possible to add your Meilisearch settings configuration to the indexes you create using the settings field in the plugin configuration file.

The settings are added when either: adding a content-type to Meilisearch or when updating a content-type in Meilisearch. The settings are not updated when documents are added through the listeners.

For example

module.exports = {
  meilisearch: {
    config: {
      restaurant: {
        settings: {
          filterableAttributes: ['categories'],
          synonyms: {
            healthy: ['pokeball', 'vegan']
          }
        }
      }
    }
  },
}

See resources for more settings examples.

πŸ”Ž Entries query

When indexing a content type to Meilisearch, the plugin has to fetch the documents from your database. With entriesQuery it is possible to specify some options are applied during the fetching of the entries. The options you can set are described in the findMany documentation of Strapi. However, we do not accept any changes on the start parameter.

Common use cases

If you are using the 🌍 Internationalization (i18n) plugin, an additional field locale can also be added in entriesQuery.

If you want to add a collection with a relation to the collection being included, you have to configure the populate parameter in entriesQuery. See the docs on how it works, and an example in our resources.

Example

If you want your documents to be fetched in batches of 1000 you specify it in the entriesQuery option.

module.exports = {
  meilisearch: {
    config: {
      restaurant: {
        entriesQuery: {
          limit: 1000
        }
      }
    }
  },
}

See resources for more entriesQuery examples.

πŸ” Selectively index private fields

Private fields are sanitized by default to prevent data leaks. However, you might want to allow some of these private fields to be used for search, filter or sort. This is possible with the noSanitizePrivateFields. For example, if you have a private field called internal_notes in your content-type schema that you wish to include in searching, you can add it to the noSanitizePrivateFields array to allow it to be indexed.

// config/plugins.js

module.exports = {
  meilisearch: {
    config: {
      restaurant: {
        noSanitizePrivateFields: ["internal_notes"], // All attributes: ["*"]
        settings:  {
          "searchableAttributes": ["internal_notes"],
        }
      },
    },
  },
}

πŸ•΅οΈβ€β™€οΈ Start Searching

Once you have a content-type indexed in Meilisearch, you can start searching.

To search in Meilisearch, you can use the instant-meilisearch library that integrates a whole search interface, or our meilisearch-js SDK.

⚑️ Using Instant Meilisearch

You can have a front up and running in record time with instant-meilisearch.

Restaurant demo

In Instant Meilisearch, you only have to provide your credentials and index name (uid). restaurant is the index name in our example.

You can have a quick preview with the following code in an HTML file. Create an HTML file, copy-paste the code below and open the file in your browser (or find it in /front_examples/restaurant.html).

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="utf-8" />
    <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@meilisearch/instant-meilisearch/templates/basic_search.css" />
  </head>
  <body>
    <div class="wrapper">
      <div id="searchbox" focus></div>
      <div id="hits"></div>
    </div>
    <script src="https://cdn.jsdelivr.net/npm/@meilisearch/instant-meilisearch/dist/instant-meilisearch.umd.min.js"></script>
    <script src="https://cdn.jsdelivr.net/npm/instantsearch.js@4"></script>
    <script>
        const search = instantsearch({
            indexName: "restaurant",
            searchClient: instantMeiliSearch(
                "http://localhost:7700",
                'publicKey', // Use the public key not the private or master key to search.
            )
            });

            search.addWidgets([
              instantsearch.widgets.searchBox({
                  container: "#searchbox"
              }),
              instantsearch.widgets.configure({ hitsPerPage: 8 }),
              instantsearch.widgets.hits({
                  container: "#hits",
                  templates: {
                  item: `
                      <div>
                      <div class="hit-name">
                          {{#helpers.highlight}}{ "attribute": "name" }{{/helpers.highlight}}
                      </div>
                      </div>
                  `
                  }
              })
            ]);
            search.start();
    </script>
  </body>
</html>

πŸ’› Using Meilisearch for JS

You can also use meilisearch-js to communicate with Meilisearch.

The following code is a setup that will output a restaurant after a search.

import { MeiliSearch } from 'meilisearch'

;(async () => {
  const client = new MeiliSearch({
    host: 'http://127.0.0.1:7700',
    apiKey: 'publicKey', // Use the public key not the private or master key to search.
  })

  // An index is where the documents are stored.
  const response = client.index('movies').search('Biscoutte')
})()

response content:

{
  "hits": [
    {
      "id": 3,
      "name": "Biscotte Restaurant",
      "description": "Welcome to Biscotte restaurant! Restaurant Biscotte offers a cuisine based on fresh, quality products, often local, organic when possible, and always produced by passionate producers.",
      "categories": []
    }
  ],
  "offset": 0,
  "limit": 20,
  "nbHits": 1,
  "exhaustiveNbHits": false,
  "processingTimeMs": 1,
  "query": "biscoutte"
}

πŸ’‘ Run the Playground

Instead of adding the plugin to an existing project, you can try it out using the playground in this project.

# Root of repository
yarn playground:build # Build the playground
yarn playground:dev # Start the development server

This command will install the required dependencies and launch the app in development mode. You should be able to reach it on the port 8000 of your localhost.

πŸ€– Compatibility with Meilisearch and Strapi

Supported Strapi versions:

Complete installation requirements are the same as for Strapi itself and can be found in the documentation under installation Requirements.

  • Strapi >=v4.x.x

If you are using Strapi v3, please refer to this README.

Supported Meilisearch versions:

This package guarantees compatibility with version v1.x of Meilisearch, but some features may not be present. Please check the issues for more info.

Node:

  • NodeJS >= 18

We recommend always using the latest version of Strapi to start your new projects.

βš™οΈ Development Workflow and Contributing

Any new contribution is more than welcome in this project!

If you want to know more about the development workflow or want to contribute, please visit our contributing guidelines for detailed instructions!

🌎 Community support

🀩 Just for the pleasure of the eyes

Using the foodadvisor restaurant demo Strapi provided. We added a searchbar to it using instant-meilisearch.

Fooradvisor demo

strapi-plugin-meilisearch's People

Contributors

aloulouamine avatar bidoubiwa avatar brunoocasali avatar carofg avatar curquiza avatar dependabot[bot] avatar dzcpy avatar escwxyz avatar hazya avatar kazdan1994 avatar kimiiz55 avatar liquiditguy avatar marekbodinger avatar matepaiva avatar meili-bors[bot] avatar meili-bot avatar mimartinez avatar nhvu1988 avatar nicolasvienot avatar oluademola avatar pablo-aldana avatar romitkarmakar avatar yannicschroeer avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar

strapi-plugin-meilisearch's Issues

Create proper README

The README should explain how to launch the strapi plugin and add it to your own project.

This might be at first using git clone and once we have added it to the npm package manager we will update the README accordingly.

Reload server should bring back to plugin page

Whenever a user clicks on reload button

Screenshot 2021-03-25 at 10 59 10

The app is completely rebooted and the user is redirected to the sign-in page of the admin dashboard.
But when the user adds a new Content-Type, the reload bring the user back to the content-type page.

It should be found how to copy the behavior of Content-type reload.

Add collections documents in batches

For now all documents of collections are added in one push on MeiliSearch. This is not an issue until the dataset in the collection is massive. In which case the document addition should be split in batches. This behaviour could be added by default, where we always send documents with batches of 1000 documents.

  • change addDocuments pushes with batches of 1000 documents
  • change wait for pending update in collections.js component that only watches one update id. it should look for all update ids of the given UID

Link Collections with MeiliSearch

Replace previously input tag with a direct possibility to chose a Collection to index to MeiliSearch

  • User chooses a collection amongst all its displayed collections
  • Communication is done to MeiliSearch that gets index names (Collection name) and its documents
  • Create UI where all collections are shown

Meilisearch can't work with Strapi single type content

node v14.16.0
strapi v3.5.4
strapi-plugin-meilisearch v0.2.0
ubuntu v20.04

Hi there,

I spotted an issue inside numberOfRowsInCollection function.
Indeed, I get strapi.services[collection].count is not a function
But if I the function returns 1 it works.

The problem comes from Strapi single type content.
In my case, I had an Home Page single type content.
Once removed, it's perfectly fine.

It's only because, you can't count on a Strapi single type content.

Nevertheless, Meilisearch doesn't should fetch this kind of "collection".

Ask in a modal for user to reload on Collection addition

Using the Modal component provided by strapi-helper-plugin

A Modal should be created an open whenever a reload is needed on Collection addition on MeiliSearch

  1. Add a collection to MeiliSearch
  2. Modal opens asking for reload to activate hooks
  3. Possibility to say no -> closes modals
  4. Possibility to say yes -> Reload server

If option 3 is chosen the option to reload the server with the red button in the bottom right of the page should still appear

Make it possible to chose which sub-fields of the related collection we should keep

Problem

If you have a collection in Strapi that has a relation with another collection, once you index it to MeiliSearch the output is the following:

 {
    "id": 2,
    "name": "Italian",
    "restaurants": [
      {
        "id": 1,
        "name": "PetitPatapon",
        "description": "Delicieux",
        "created_by": 1,
        "updated_by": 1,
        "created_at": "2021-03-03T12:09:10.979Z",
        "updated_at": "2021-03-03T12:09:10.988Z"
      },
      {
        "id": 2,
        "name": "LaLoLaLiTa",
        "description": "Ma que bello",
        "created_by": 1,
        "updated_by": 1,
        "created_at": "2021-03-03T12:17:46.503Z",
        "updated_at": "2021-03-03T12:17:46.515Z"
      }
    ]
  },

But for MeiliSearch to create facets the best way would be to transform the restaurants object into the following:

 {
    "id": 2,
    "name": "Italian",
    "restaurants": ["LaLoLaLiTa", "PetitPatapon"]
 },

Solution

It would be better that on indexation, if a relation is discovered, the user is prompted to chose one field or to ignore the questions.

Base UI elements

Add the following UI elements:

  • Host and Keys
  • Index name input
  • Documents input json

Ensure fetching of collections rows is done using the controller

When adding a collection to MeiliSearch it fetches the rows using the service methods:

await strapi.services[collection].find({ _publicationState: 'preview' })

If this is using the models instead of the controller we might miss on data transformation that has been added by the strapi user.

How to handle single types

Appart from Collection types in Strapi, that acts as a SQL table with many rows, there are also single types.

Collection types are added straightforwardly to MeiliSearch as we just index all rows.
But single types are only composed of one element.

The use case of single types are mostly content manager if I understand correctly. Meaning that one type represent the content of one element.

We could go in three directions with this:

1. Ignore single types

Speaks for itself

2. Accept one single type to be indexed in one index

This option does not make sense but could be useful in some rare use cases

3. Index all singles type in the same single-types index.

Because single types are content managers, we might want to index them all together.
If the use case is indeed that, it would make it possible for users to search inside all content types at once, and thus create a search experience on the content of the website rather than on the products stored in collecrtions

Make e2e tests on all possible environments

As of today tests are only done on strapi start in no-reload mode.
It would be better if we tried the following as well

  • strapi develop
  • strapi develope --admin-watch
  • NODE_ENV=production strapi start

I tried adding this to the yaml file as it works locally but at the second tests it fails:

      - name: Test develop admin watch
        uses: cypress-io/github-action@v2
        with:
          build: yarn playground:build
          start: yarn playground:dev
          env: env=watch
      - name: Test develop soft watch
        uses: cypress-io/github-action@v2
        with:
          build: yarn playground:build
          start: yarn playground:dev
          env: env=develop
      - name: Test production
        uses: cypress-io/github-action@v2
        with:
          build: yarn playground:build
          start: yarn playground:dev
          env: env=ci

Maybe they just need to be separated in a different job each?

Hooks are not adding more than 100 documents on afterCreate

As it appears when adding a huge dataset to MeiliSearch it stops at 100 entries.
As this is not the expected behavior it is a bug.

queue.on('ready', function () {
    queue.process(function (job, done) {
      console.log('processing job ' + job.id);
      console.log('job data page: ', job.data.page);
      const mockCtx = {
        params: { collection: job.data.collection },
        send: (e) => e,
        request: {},
      };
      fetchCollection(mockCtx, { page: job.data.page })
        .then((r) => addCollectionRows(r))
        .catch((e) => console.log('queue error', e));
      console.log('processed job ' + job.data.page);
      setTimeout(function () {
        done(null, job.data.id);
      }, 10);
    });

    console.log('listening for jobs and processing queued jobs...');
  });
};

@MANTENN , lets continue here!

Could you try the following:

  1. Add your documents using the hooks
  2. Bug appears! there are only 100 entries.
  3. Using your meilisearch credentials try this route: https://docs.meilisearch.com/reference/api/updates.html#get-all-update-status

It should give back status on your document addition in MeiliSearch. Could you copy paste it here?

Also, is there a error thrown in the server logs?

Add integrations tests

e2e tests have been added but we should probably add intΓ©grations and unit tests as well to try out the back-end API.

Because of the global variables it's hard to mock everything. Which leads to complex mocking to be able to test all methods.

Make it possible to add Collection to MeiliSearch without dashboard

To add collections to MeiliSearch, the proposed method is to go on the MeiliSearch plugin page that is visible on your homepage.

Once there, after adding the right credentials clicking on the checkbox of your collection will add it to MeiliSearch.

It should also be possible to do the exact same process without having to use the dashboard but by using the appropriate routes:
POST /services/meilisearch/collection

It is possible that this is already possible. I just did not try it yet.

ERROR: Cannot destructure property 'updateId' of '(intermediate value)' as it is undefined.

Current behavior
The bellow error gets thrown when trying to reload the server after adding a the plugin on search. Hooks section is stuck at "Realoded Needed"

Logs

This error originated either by throwing inside of an async function without a catch block, or by rejecting a promise which was not handled with .catch(). The promise rejected with the reason:
TypeError: Cannot destructure property 'updateId' of '(intermediate value)' as it is undefined.
at batchAddCollection (/xxxxx/node_modules/strapi-plugin-meilisearch/controllers/meilisearch.js:147:13)

Environment (please complete the following information):

  • OS: MacOS BigSUR
  • MeiliSearch version: [v.0.20.0]
  • strapi-plugin-meilisearch version: [v0.2.1]
  • Strapi version: [v3.6.3]

Add previewed rows as well

Add an option to add both published rows and draft rows as for now, only published rows are indexed in MeilISearch.

With draft rows

const entity = await strapi.services[indexUid].find({ _publicationState: 'preview' })

Without draft rows

const rows = await strapi.services[indexUid].find()

STEP 2: Connecting with MeiliSearch

  • #10 Base UI elements
  • #9 Back end communication with MeiliSearch

-> This Creates a working version of MeiliSearch on Strapi but does not communicate with strapi yet

Add linter

Add a linting tool and style tests to keep the code base clean

  • eslint
  • editorconfig
  • bors
  • dependabot

Improve error handler

  • Hide API key in error message when API key is wrong
  • Make error visual more comprehensive

Update cypress to v7

To update the cypress version to v7 in this repository breaking changes must be fixed!

MVP of this plugin

MVP

  • Downloadable plugin (package manager)
  • Communication with a running MeiliSearch
  • Interface with the following:
    • Add host and keys
    • Ability to chose which collections should be indexed in MeiliSearch
    • Every time a collection is updated, the updated element should be updated in MeiliSearch as well (hook to add, edit and delete)
    • Possibility to remove a collection from MeiliSearch

Possible addition after MVP

  • Preview of search on the plugin page.
  • Possibility to add relations between Collections. Exemple: Given 2 collections, restaurants and users, facet

Change linking to components

I would like to avoid having to use links like this

import { Wrapper } from '../components/Wrapper'

But would rather do the following:

import { Wrapper } from 'components/Wrapper'

It is possible by changing the compiler options on a strapi app but the plugin is not compiled independently.

Create architecture

On the project architecture there should be the following:

  • ./meilisearch: the content of the plugin
  • ./playground: the Strapi playgrounds used to develop the plugin in watch mode

MeiliSearchApiError: request , it doesn't matter whether or not a "masterKey" is passed.

Bug when trying to update a collection after configuring MeiliSearch.
It doesn't matter whether or not I create a "masterKey". The error "Could not connect with MeiliSearch ECONNREFUSED" is always returned.

How to reproduce. Run MeiliSearch passing parameter "MEILI_MASTER_KEY=masterKey" in development environment. When trying to add the collections to index the error mentioned above is reported.

It was tried to run without passing the "masterKey" information so that there was no restriction and even so the same access error was reported.
Screenshot from 2021-06-01 17-10-34

Handle multi languages plugin

Problem

For now the plugin only works in English as the text has been hard-coded inside the different components.

Solution

Strapi provided a very good way to handle multiple languages.
It has been tried in the header of the MeiliSearch plugin meilisearch/admin/src/containers/HomePage/index.js

<Header
            title={{
              label: formatMessage({ id: getTrad('plugin.name') })
            }}
            content={formatMessage({ id: getTrad('header.description') })}
          />

The text is imported from meilisearch/admin/src/translations.

We should change all hard-coded text with the same feature.

Example

'Indexed In MeiliSearch'

should become

// collections.js
formatMessage({ id: getTrad('collection.indexed') })

And the following should be added in at least en

//meilisearch/admin/src/translations
"collection.indexed": "Indexed in MeiliSearch"

Whats next

Once this is done, it will be very easy to add new languages to the plugin

Add testing

Find a way to tests both back-end and generated UI.

  • e2e
  • Integrations tests

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    πŸ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. πŸ“ŠπŸ“ˆπŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❀️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.