### 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.