### Install required packages for Medusa search Source: https://github.com/rokmohar/medusa-plugin-meilisearch/blob/main/nextjs/README.md Install the necessary npm packages, `@meilisearch/instant-meilisearch` and `react-instantsearch`, to enable search features in your Medusa Next.js storefront. ```Shell npm install @meilisearch/instant-meilisearch@^0.24.0 react-instantsearch@^7.15.3 ``` -------------------------------- ### Install Medusa MeiliSearch Plugin Source: https://github.com/rokmohar/medusa-plugin-meilisearch/blob/main/README.md Install the Medusa MeiliSearch plugin as a dependency in your project using either npm or yarn. ```bash npm install --save @rokmohar/medusa-plugin-meilisearch ``` ```bash yarn add @rokmohar/medusa-plugin-meilisearch ``` -------------------------------- ### Create a Basic GET API Route in Medusa Source: https://github.com/rokmohar/medusa-plugin-meilisearch/blob/main/src/api/README.md Demonstrates how to create a simple GET API endpoint at `/store/hello-world` using file-based routing in Medusa, returning a JSON message. The route is defined in a `route.ts` file within the specified directory structure. ```TypeScript import type { MedusaRequest, MedusaResponse } from '@medusajs/framework/http' export async function GET(req: MedusaRequest, res: MedusaResponse) { res.json({ message: 'Hello world!', }) } ``` -------------------------------- ### Create Custom Workflow with Medusa Workflows SDK Source: https://github.com/rokmohar/medusa-plugin-meilisearch/blob/main/src/workflows/README.md This example demonstrates how to define a custom workflow using the `@medusajs/workflows-sdk`. It illustrates the creation of individual steps, `createStep`, and their composition into a complete workflow using `createWorkflow`. The snippet also defines input and output types for the workflow. ```typescript import { createStep, createWorkflow, WorkflowResponse, StepResponse } from '@medusajs/workflows-sdk' const step1 = createStep('step-1', async () => { return new StepResponse(`Hello from step one!`) }) type WorkflowInput = { name: string } const step2 = createStep('step-2', async ({ name }: WorkflowInput) => { return new StepResponse(`Hello ${name} from step two!`) }) type WorkflowOutput = { message1: string message2: string } const helloWorldWorkflow = createWorkflow('hello-world', (input: WorkflowInput) => { const greeting1 = step1() const greeting2 = step2(input) return new WorkflowResponse({ message1: greeting1, message2: greeting2, }) }) export default helloWorldWorkflow ``` -------------------------------- ### Medusa Storefront API: Search Products Endpoint Source: https://github.com/rokmohar/medusa-plugin-meilisearch/blob/main/README.md This section documents the `/store/products/search` API endpoint for searching products. It specifies the HTTP method, query parameters (`query` and optional `language`), and provides an example of a basic search request in French. ```http GET /store/products/search ``` ```APIDOC Query Parameters: - `query`: Search query string - `language`: (Optional) Language code to search in ``` ```http # Basic search in French GET /store/products/search?query=shirt&language=fr ``` -------------------------------- ### Configure Meilisearch Environment Variables for Medusa Plugin Source: https://github.com/rokmohar/medusa-plugin-meilisearch/blob/main/README.md This snippet provides the necessary environment variables (`MEILISEARCH_HOST`, `MEILISEARCH_API_KEY`) for connecting the Medusa plugin to a Meilisearch instance. It includes default values for local development with the provided `docker-compose` setup. ```env # ... others vars MEILISEARCH_HOST= MEILISEARCH_API_KEY= ``` ```env # ... others vars MEILISEARCH_HOST=http://127.0.0.1:7700 MEILISEARCH_API_KEY=ms ``` -------------------------------- ### Example Medusa Scheduled Job Implementation Source: https://github.com/rokmohar/medusa-plugin-meilisearch/blob/main/src/jobs/README.md This TypeScript example demonstrates how to define a custom scheduled job in Medusa. It includes an asynchronous handler function that resolves the `product` service to list products, and a `config` object that sets the job's unique name (`daily-product-report`) and its cron schedule (`0 0 * * *`) to run daily at midnight. The handler function receives a `MedusaContainer` instance for service access. ```ts import { MedusaContainer } from '@medusajs/framework/types' export default async function myCustomJob(container: MedusaContainer) { const productService = container.resolve('product') const products = await productService.listAndCountProducts() // Do something with the products } export const config = { name: 'daily-product-report', schedule: '0 0 * * *', // Every day at midnight } ``` -------------------------------- ### Medusa Subscriber with Parameters and Service Resolution (TypeScript) Source: https://github.com/rokmohar/medusa-plugin-meilisearch/blob/main/src/subscribers/README.md This example shows a more advanced Medusa subscriber that accesses event data and resolves services from the Medusa container. The `productCreateHandler` function extracts the product ID from the event data, resolves the `product` module service, retrieves the product details, and logs its title upon creation. ```ts import type { SubscriberArgs, SubscriberConfig } from '@medusajs/framework' export default async function productCreateHandler({ event: { data }, container }: SubscriberArgs<{ id: string }>) { const productId = data.id const productModuleService = container.resolve('product') const product = await productModuleService.retrieveProduct(productId) console.log(`The product ${product.title} was created`) } export const config: SubscriberConfig = { event: 'product.created', } ``` -------------------------------- ### Create a Product Widget in Medusa Admin Source: https://github.com/rokmohar/medusa-plugin-meilisearch/blob/main/src/admin/README.md This snippet demonstrates how to create a React component widget and inject it into an existing page in the Medusa Admin dashboard. The example shows a simple widget displaying 'Product Widget' on a product's details page after the default content. ```tsx import { defineWidgetConfig } from '@medusajs/admin-sdk' // The widget const ProductWidget = () => { return (

Product Widget

) } // The widget's configurations export const config = defineWidgetConfig({ zone: 'product.details.after', }) export default ProductWidget ``` -------------------------------- ### Access Medusa Module Service in API Route Source: https://github.com/rokmohar/medusa-plugin-meilisearch/blob/main/src/modules/README.md This example demonstrates how to access and use a custom Medusa module's service within an API route. It resolves the `BlogModuleService` from the request scope and uses it to list posts. ```ts import { MedusaRequest, MedusaResponse } from '@medusajs/framework' import BlogModuleService from '../../../modules/blog/service' import { BLOG_MODULE } from '../../../modules/blog' export async function GET(req: MedusaRequest, res: MedusaResponse): Promise { const blogModuleService: BlogModuleService = req.scope.resolve(BLOG_MODULE) const posts = await blogModuleService.listPosts() res.json({ posts, }) } ``` -------------------------------- ### Define Handlers for Multiple HTTP Methods in Medusa API Routes Source: https://github.com/rokmohar/medusa-plugin-meilisearch/blob/main/src/api/README.md Illustrates how to export functions for different HTTP methods (GET, POST, PUT) within a single `route.ts` file to handle various request types for a Medusa API route. This allows a single endpoint to respond differently based on the HTTP verb. ```TypeScript import type { MedusaRequest, MedusaResponse } from '@medusajs/framework/http' export async function GET(req: MedusaRequest, res: MedusaResponse) { // Handle GET requests } export async function POST(req: MedusaRequest, res: MedusaResponse) { // Handle POST requests } export async function PUT(req: MedusaRequest, res: MedusaResponse) { // Handle PUT requests } ``` -------------------------------- ### Apply search patch to Medusa Next.js starter Source: https://github.com/rokmohar/medusa-plugin-meilisearch/blob/main/nextjs/README.md This command applies the `search.patch` file to your Medusa Next.js starter project, integrating the necessary code changes for search functionality. ```Shell git apply search.patch ``` -------------------------------- ### Configure environment variables for Medusa search Source: https://github.com/rokmohar/medusa-plugin-meilisearch/blob/main/nextjs/README.md Set these environment variables in your project's `.env` file to enable and configure the search feature, specifying the search endpoint, API key, and index name. ```Shell NEXT_PUBLIC_FEATURE_SEARCH_ENABLED=true NEXT_PUBLIC_SEARCH_ENDPOINT=http://127.0.0.1:7700 NEXT_PUBLIC_SEARCH_API_KEY=ms NEXT_PUBLIC_INDEX_NAME=products ``` -------------------------------- ### Basic Medusa Subscriber for Product Creation (TypeScript) Source: https://github.com/rokmohar/medusa-plugin-meilisearch/blob/main/src/subscribers/README.md This snippet demonstrates the basic structure of a Medusa subscriber. It defines an asynchronous function `productCreateHandler` that logs a message when a product is created, and exports a configuration object `config` to associate the subscriber with the `product.created` event. ```ts import { type SubscriberConfig } from '@medusajs/framework' // subscriber function export default async function productCreateHandler() { console.log('A product was created') } // subscriber config export const config: SubscriberConfig = { event: 'product.created', } ``` -------------------------------- ### Sync Medusa Module Links to Database using CLI Source: https://github.com/rokmohar/medusa-plugin-meilisearch/blob/main/src/links/README.md After defining module links, this command is used in the Medusa application to synchronize the newly defined links with the database, ensuring they are persisted and active. ```bash npx medusa db:migrate ``` -------------------------------- ### Access Path Parameters in Medusa API Routes Source: https://github.com/rokmohar/medusa-plugin-meilisearch/blob/main/src/api/README.md Shows how to define an API route that accepts a path parameter (e.g., `productId`) by creating a `[param]` directory in the file path. It also demonstrates how to access these parameters from the `req.params` object within the route handler. ```TypeScript import type { MedusaRequest, MedusaResponse } from '@medusajs/framework/http' export async function GET(req: MedusaRequest, res: MedusaResponse) { const { productId } = req.params res.json({ message: `You're looking for product ${productId}`, }) } ``` -------------------------------- ### Docker Compose Configuration for Meilisearch Service Source: https://github.com/rokmohar/medusa-plugin-meilisearch/blob/main/README.md This YAML snippet provides a `docker-compose` service definition for running Meilisearch. It includes port mapping, volume mounting for data persistence, environment variables for the master key, and a health check to ensure the service is running correctly. ```yaml services: # ... other services meilisearch: image: getmeili/meilisearch:latest ports: - '7700:7700' volumes: - ~/data.ms:/data.ms environment: - MEILI_MASTER_KEY=ms healthcheck: test: ['CMD', 'curl', '-f', 'http://localhost:7700'] interval: 10s timeout: 5s retries: 5 ``` -------------------------------- ### Generate Medusa Module Database Migrations Source: https://github.com/rokmohar/medusa-plugin-meilisearch/blob/main/src/modules/README.md This command generates database migrations for the custom Medusa module, ensuring that the defined data models are properly reflected in the database schema. ```bash npx medusa plugin:db:genreate ``` -------------------------------- ### Export Medusa Module Definition Source: https://github.com/rokmohar/medusa-plugin-meilisearch/blob/main/src/modules/README.md This snippet shows how to export the module definition in `index.ts`. It registers the `BlogModuleService` as the main service for the 'blog' module, making it discoverable by Medusa. ```ts import BlogModuleService from './service' import { Module } from '@medusajs/framework/utils' export const BLOG_MODULE = 'blog' export default Module(BLOG_MODULE, { service: BlogModuleService, }) ``` -------------------------------- ### Implement Medusa Module Service Class Source: https://github.com/rokmohar/medusa-plugin-meilisearch/blob/main/src/modules/README.md This code defines a service class for a Medusa module. It extends `MedusaService` and associates the previously defined `Post` model, providing a foundation for business logic. ```ts import { MedusaService } from '@medusajs/framework/utils' import Post from './models/post' class BlogModuleService extends MedusaService({ Post, }) {} export default BlogModuleService ``` -------------------------------- ### Configure Medusa MeiliSearch Plugin in medusa-config.ts Source: https://github.com/rokmohar/medusa-plugin-meilisearch/blob/main/README.md Add and configure the MeiliSearch plugin in your `medusa-config.ts` file. This includes setting MeiliSearch host and API key, defining index settings for products (searchable, displayed, filterable attributes, primary key), and configuring i18n options for language strategies and translatable fields. ```javascript import { loadEnv, defineConfig } from '@medusajs/framework/utils' import { MeilisearchPluginOptions } from '@rokmohar/medusa-plugin-meilisearch' loadEnv(process.env.NODE_ENV || 'development', process.cwd()) module.exports = defineConfig({ // ... other config plugins: [ // ... other plugins { resolve: '@rokmohar/medusa-plugin-meilisearch', options: { config: { host: process.env.MEILISEARCH_HOST ?? '', apiKey: process.env.MEILISEARCH_API_KEY ?? '' }, settings: { // The key is used as the index name in Meilisearch products: { // Required: Index type type: 'products', // Optional: Whether the index is enabled. When disabled: // - Index won't be created or updated // - Documents won't be added or removed // - Index won't be included in searches // - All operations will be silently skipped enabled: true, // Optional: Specify which fields to include in the index // If not specified, all fields will be included fields: ['id', 'title', 'description', 'handle', 'variant_sku', 'thumbnail'], indexSettings: { searchableAttributes: ['title', 'description', 'variant_sku'], displayedAttributes: ['id', 'handle', 'title', 'description', 'variant_sku', 'thumbnail'], filterableAttributes: ['id', 'handle'] }, primaryKey: 'id', // Create your own transformer /*transformer: (product) => ({ id: product.id, // other attributes... }),*/ } }, i18n: { // Choose one of the following strategies: // 1. Separate index per language // strategy: 'separate-index', // languages: ['en', 'fr', 'de'], // defaultLanguage: 'en', // 2. Language-specific fields with suffix strategy: 'field-suffix', languages: ['en', 'fr', 'de'], defaultLanguage: 'en', translatableFields: ['title', 'description'] } } satisfies MeilisearchPluginOptions } ] }) ``` -------------------------------- ### Apply Custom Middleware to Medusa API Routes Source: https://github.com/rokmohar/medusa-plugin-meilisearch/blob/main/src/api/README.md Demonstrates how to define and apply custom middleware functions to specific API routes by creating a `/api/middlewares.ts` file. This file exports a configuration object with `matcher` (string or regex) and `middlewares` (array of functions) properties to control middleware application. ```TypeScript import { defineMiddlewares } from '@medusajs/framework/http' import type { MedusaRequest, MedusaResponse, MedusaNextFunction } from '@medusajs/framework/http' async function logger(req: MedusaRequest, res: MedusaResponse, next: MedusaNextFunction) { console.log('Request received') next() } export default defineMiddlewares({ routes: [ { matcher: '/store/custom', middlewares: [logger], } ] }) ``` -------------------------------- ### Execute Medusa Workflow in an API Route Source: https://github.com/rokmohar/medusa-plugin-meilisearch/blob/main/src/workflows/README.md This snippet shows how to execute a custom Medusa workflow, such as `hello-world`, from within an API route. It imports the workflow, runs it with input derived from the `MedusaRequest`, and sends the workflow's result back via `MedusaResponse`. ```typescript import type { MedusaRequest, MedusaResponse } from '@medusajs/framework' import myWorkflow from '../../../workflows/hello-world' export async function GET(req: MedusaRequest, res: MedusaResponse) { const { result } = await myWorkflow(req.scope).run({ input: { name: req.query.name as string, }, }) res.send(result) } ``` -------------------------------- ### Configure Medusa Plugin Module Options Source: https://github.com/rokmohar/medusa-plugin-meilisearch/blob/main/src/modules/README.md This snippet illustrates how to pass options to a custom module when registering its parent plugin in the Medusa application's configuration. These options can then be accessed by the module's services. ```ts import { defineConfig } from '@medusajs/framework/utils' module.exports = defineConfig({ // ... plugins: [ { resolve: '@myorg/plugin-name', options: { apiKey: process.env.API_KEY, }, } ] }) ``` -------------------------------- ### Basic i18n Configuration for Medusa MeiliSearch Plugin Source: https://github.com/rokmohar/medusa-plugin-meilisearch/blob/main/README.md Configure basic internationalization settings for the MeiliSearch plugin, including the chosen strategy ('separate-index' or 'field-suffix'), a list of supported languages, the default fallback language, and a list of simple translatable fields. ```typescript { i18n: { // Choose strategy: 'separate-index' or 'field-suffix' strategy: 'field-suffix', // List of supported languages languages: ['en', 'fr', 'de'], // Default language to fall back to defaultLanguage: 'en', // Optional: List of translatable fields translatableFields: ['title', 'description', 'handle'] } } ``` -------------------------------- ### Define Module Link between Product and Blog Posts in TypeScript Source: https://github.com/rokmohar/medusa-plugin-meilisearch/blob/main/src/links/README.md This snippet demonstrates how to define a module link using `defineLink` from `@medusajs/framework/utils`. It creates an association between the `product` data model of the Product Module and the `post` data model of a custom Blog Module, maintaining module isolation. ```ts import BlogModule from '../modules/blog' import ProductModule from '@medusajs/medusa/product' import { defineLink } from '@medusajs/framework/utils' export default defineLink(ProductModule.linkable.product, BlogModule.linkable.post) ``` -------------------------------- ### Define Medusa Module Data Model Source: https://github.com/rokmohar/medusa-plugin-meilisearch/blob/main/src/modules/README.md This snippet demonstrates how to define a data model for a custom Medusa module. It creates a 'Post' model with an ID and title, representing a database table. ```ts import { model } from '@medusajs/framework/utils' const Post = model.define('post', { id: model.id().primaryKey(), title: model.text(), }) export default Post ``` -------------------------------- ### Access Medusa Container Services in API Routes Source: https://github.com/rokmohar/medusa-plugin-meilisearch/blob/main/src/api/README.md Explains how to resolve and use Medusa's registered services (e.g., `product` module service) from the `req.scope` object within an API route handler. This allows routes to interact with core Medusa functionalities like listing products. ```TypeScript import type { MedusaRequest, MedusaResponse } from '@medusajs/framework/http' export const GET = async (req: MedusaRequest, res: MedusaResponse) => { const productModuleService = req.scope.resolve('product') const [, count] = await productModuleService.listAndCount() res.json({ count, }) } ``` -------------------------------- ### Implement Custom Product Translation Transformer in Medusa Meilisearch Plugin Source: https://github.com/rokmohar/medusa-plugin-meilisearch/blob/main/README.md This TypeScript snippet demonstrates how to provide custom product translations to the Medusa Meilisearch plugin's transformer. It shows fetching translations from an external source and integrating them with the `transformProduct` utility, allowing flexible i18n without relying on specific storage formats. ```typescript import { transformProduct } from '@rokmohar/medusa-plugin-meilisearch' const getProductTranslations = async (productId: string) => { // Example: fetch from your translation service/database return { title: [ { language_code: 'en', value: 'Blue T-Shirt' }, { language_code: 'fr', value: 'T-Shirt Bleu' } ], description: [ { language_code: 'en', value: 'A comfortable blue t-shirt' }, { language_code: 'fr', value: 'Un t-shirt bleu confortable' } ] } } // Example usage in your custom transformer const customTransformer = async (product, options) => { const translations = await getProductTranslations(product.id) return transformProduct(product, { ...options, translations }) } ``` -------------------------------- ### Medusa Scheduled Job Definition API Reference Source: https://github.com/rokmohar/medusa-plugin-meilisearch/blob/main/src/jobs/README.md Reference for defining a custom scheduled job in Medusa, detailing the required default export handler function and the named `config` object with its properties. ```APIDOC Scheduled Job File Exports: 1. Default Export (Handler Function): Signature: (container: MedusaContainer) => Promise container: MedusaContainer description: An instance of MedusaContainer used to resolve services. Purpose: The function to be executed whenever the scheduled job runs. 2. Named Export (config Object): Name: config Type: object Properties: name: string (required) description: A unique name for the job. schedule: string (required) description: A cron expression (e.g., '0 0 * * *' for daily at midnight). numberOfExecutions: integer (optional) description: Specifies how many times the job will execute before being removed. ``` -------------------------------- ### Advanced i18n Field Configuration for Medusa MeiliSearch Plugin Source: https://github.com/rokmohar/medusa-plugin-meilisearch/blob/main/README.md Set up advanced internationalization for specific fields. This allows you to define a source field, specify a different target name for the indexed field, and apply a custom transformation function to the field's value before it is indexed. ```typescript { i18n: { strategy: 'field-suffix', languages: ['en', 'fr', 'de'], defaultLanguage: 'en', translatableFields: [ // Simple field name 'title', // Field with different target name { source: 'description', target: 'content' // Will be indexed as content_en, content_fr, etc. }, // Field with transformation { source: 'handle', transform: (value) => value.toLowerCase().replace(/\s+/g, '-') } ] } } ``` -------------------------------- ### Configure Translatable Fields for Medusa Meilisearch Plugin Source: https://github.com/rokmohar/medusa-plugin-meilisearch/blob/main/README.md This TypeScript configuration snippet shows how to explicitly define `translatableFields` when using the `field-suffix` i18n strategy. This overrides the plugin's automatic detection of string fields, ensuring only specified fields are translated. ```typescript { i18n: { strategy: 'field-suffix', languages: ['en', 'fr'], defaultLanguage: 'en', // Only these fields will be translatable translatableFields: ['title', 'description'] } } ``` === COMPLETE CONTENT === This response contains all available snippets from this library. No additional content exists. Do not make further requests.