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)
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.
// store/src/lib/strapi-client/get-option-translations.tsexport 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):
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);});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
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)
- 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:
export interface CountdownBlock { __component: "ui.countdown-block" id: number title?: string target_date: string} // Añadir al union typeexport type HomepageBlock = | ProductSplitViewBlock | ProductShowcaseBlock | FeaturesBlock | BlogPostsBlock | CategoryCollectionBlock | CountdownBlock // <-- añadido aquí- Crear Carpeta y Componente React — Crea una carpeta llamada
CountdownBlocken la rutastore/src/modules/home/components/:
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> )}- Registrar en BlockRenderer — Abre el archivo
store/src/modules/home/components/BlockRenderer/index.tsxy añade un nuevo caso al switch:
import CountdownBlock from "../CountdownBlock" // Dentro del switch(block.__component) en BlockRenderer:case "ui.countdown-block": BlockContent = <CountdownBlock block={block} /> break- Crear Esquema de Componente en Strapi — Crea un nuevo archivo JSON en la carpeta
website-admin/src/components/ui/:
{ "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
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.