DocumentaciónGuía para DesarrolladoresRecetas Rápidas de Personalización

Recetas de Personalización y Desarrollo de Nuevas Funcionalidades

Esta guía está dirigida a desarrolladores que disponen del código fuente y desean añadir funciones personalizadas, traducir opciones de productos o crear componentes visuales a medida.

Receta 1: Gestión y Traducción de Opciones de Producto y Muestras de Color (`color`)

Regla Inmutable para la Clave de Color (Color Swatches)
En el panel de administración de Medusa, el título de la opción asignada al color debe ser, sin excepción, la palabra color (o Color). El frontend de Next.js utiliza esta clave para identificar códigos de color Hex y crear círculos interactivos y filtros visuales.

Proceso para hacer multilingües los títulos de opciones con Strapi:

  • Para otras opciones (talla, material, marca), la denominación en cualquier idioma es libre.
  • Las traducciones localizadas correspondientes a los títulos de opciones se definen dinámicamente en el panel de Strapi CMS.
  • El frontend de Next.js obtiene la traducción del título desde Strapi según el Locale del usuario, mientras que la clave de filtrado permanece como color.
Ejemplo de obtención de traducción de opciones desde Strapi en el frontend
typescript
// store/src/lib/strapi-client/get-option-translations.ts
export async function getOptionTranslation(optionKey: string, locale: string = "fa") {
const res = await fetch(
`${process.env.NEXT_PUBLIC_STRAPI_URL}/api/option-translations?filters[key][$eq]=${optionKey}&locale=${locale}`,
{ headers: { Authorization: `Bearer ${process.env.STRAPI_API_TOKEN_FOR_FRONT}` } }
)
const json = await res.json()
return json.data?.[0]?.translated_name || optionKey
}

Receta 2: Añadir un Nuevo Workflow y Endpoint de API REST en Medusa v2

En Medusa v2, la lógica de negocio se organiza en Pasos (Steps) y Flujos de Trabajo (Workflows):

store-admin/src/workflows/daily-deals.ts
typescript
import { createWorkflow, createStep, StepResponse, WorkflowResponse } from "@medusajs/framework/workflows-sdk";
const fetchDealsStep = createStep("fetch-deals-step", async () => {
const deals = [{ id: "deal_1", title: "Oferta Especial del Día", discount: "25%" }];
return new StepResponse(deals);
});
export const getDailyDealsWorkflow = createWorkflow("get-daily-deals", function () {
const deals = fetchDealsStep();
return new WorkflowResponse(deals);
});
store-admin/src/api/store/daily-deals/route.ts
typescript
import { MedusaRequest, MedusaResponse } from "@medusajs/framework/http";
import { getDailyDealsWorkflow } from "../../../workflows/daily-deals";
export async function GET(req: MedusaRequest, res: MedusaResponse) {
const { result } = await getDailyDealsWorkflow(req.scope).run();
res.json({ deals: result });
}

Receta 3: Crear un Nuevo Bloque para la Página de Inicio

Los bloques de la portada se encuentran en la ruta store/src/modules/home/components/. Cada bloque consta de tres partes: una definición de tipos en homepage.ts, un esquema de Componente en Strapi y una carpeta de componente React.

Estructura Real del Proyecto
Bloques existentes como FeaturesBlock, BlogPostsBlock, ProductShowcase y ProductSplitView tienen cada uno su carpeta independiente y son identificados en el BlockRenderer mediante el __component devuelto por Strapi.

Ejemplo: Añadir un Bloque de "Cuenta Regresiva" (Countdown)

  1. Definir Tipo TypeScript — En el archivo store/src/lib/data/homepage.ts, añade la interfaz del nuevo bloque e incorpórala al tipo union principal:
store/src/lib/data/homepage.ts
typescript
export interface CountdownBlock {
__component: "ui.countdown-block"
id: number
title?: string
target_date: string
}
// Añadir al union type
export type HomepageBlock =
| ProductSplitViewBlock
| ProductShowcaseBlock
| FeaturesBlock
| BlogPostsBlock
| CategoryCollectionBlock
| CountdownBlock // <-- añadido aquí
  1. Crear Carpeta y Componente React — Crea una carpeta llamada CountdownBlock en la ruta store/src/modules/home/components/:
store/src/modules/home/components/CountdownBlock/index.tsx
tsx
import React from "react"
import type { CountdownBlock as CountdownBlockType } from "@lib/data/homepage"
interface CountdownBlockProps {
block: CountdownBlockType
}
export default function CountdownBlock({ block }: CountdownBlockProps) {
return (
<section className="py-16 text-center">
<h2 className="text-xl font-bold mb-4">{block.title}</h2>
<p className="text-gray-500">{block.target_date}</p>
</section>
)
}
  1. Registrar en BlockRenderer — Abre el archivo store/src/modules/home/components/BlockRenderer/index.tsx y añade un nuevo caso al switch:
store/src/modules/home/components/BlockRenderer/index.tsx
tsx
import CountdownBlock from "../CountdownBlock"
// Dentro del switch(block.__component) en BlockRenderer:
case "ui.countdown-block":
BlockContent = <CountdownBlock block={block} />
break
  1. Crear Esquema de Componente en Strapi — Crea un nuevo archivo JSON en la carpeta website-admin/src/components/ui/:
website-admin/src/components/ui/countdown-block.json
json
{
"collectionName": "components_ui_countdown_blocks",
"info": {
"displayName": "Countdown Block",
"icon": "clock",
"description": "A countdown timer block for the homepage"
},
"options": {},
"attributes": {
"title": { "type": "string" },
"target_date": { "type": "datetime", "required": true }
}
}
Paso Final
Tras reiniciar Strapi, ve al panel de administración Homepage > Dynamic Zone. El nuevo "Countdown Block" aparecerá en la lista de bloques disponibles.

Receta 4: Conectar un Nuevo Proveedor de Pago (Payment Provider)

Para añadir una nueva pasarela de pago, define un servicio que implemente AbstractPaymentProvider en la carpeta store-admin/src/modules/payment/ y regístralo en medusa-config.ts bajo la sección providers del módulo de pagos.