guides

Guía de Sanity CMS: Cómo Publicamos en 10 Idiomas

Escrito por Mert Batur
Apr 6, 2026
19 lectura
Guía de Sanity CMS: Cómo Publicamos en 10 Idiomas

Guía de Sanity CMS: Cómo Publicamos en 10 Idiomas

Hemos publicado más de 400 piezas de contenido en 4 sitios web y 10 idiomas a través de Sanity CMS. Esto es lo que hemos aprendido — desde el diseño de schemas hasta la publicación multilingüe automatizada.

Sanity CMS es una plataforma de contenido headless construida alrededor de contenido estructurado, un Content Lake en tiempo real y un editor basado en React llamado Sanity Studio. Usa GROQ para consultas, Portable Text para contenido enriquecido y schema-as-code para el modelado de contenido. Esta guía cubre la configuración, diseño de schemas, GROQ, Portable Text, arquitectura multilingüe y precios.

¿Qué es Sanity CMS?

Sanity es una plataforma de contenido estructurado — lo que el equipo de Sanity.io llama un "sistema operativo de contenido". A diferencia de los CMS tradicionales que almacenan blobs de HTML en una base de datos, Sanity guarda cada pieza de contenido como JSON estructurado en un backend administrado llamado Content Lake. Lo consultas con GROQ o GraphQL, y renderizas el contenido en cualquier frontend que quieras: Next.js, React Native, Svelte, una app móvil, una herramienta de CLI — lo que sea.

Las empresas que lo usan abarcan todo el espectro. Nike, Figma, Puma y Cloudflare corren Sanity a escala empresarial. Las startups lo usan porque el plan gratuito es genuinamente funcional (más sobre precios después). Nosotros lo usamos porque nada más nos dio la flexibilidad para construir un pipeline de publicación completamente automatizado en 10 idiomas.

Arquitectura del Content Lake

El Content Lake es el backend administrado de Sanity. Imagínalo como un almacén de documentos hospedado que se sincroniza en tiempo real entre todos los clientes conectados. Cuando un editor cambia un párrafo en Sanity Studio, otro editor lo ve al instante — sin botón de guardar, sin conflictos de fusión, sin migraciones de base de datos.

Internamente, los documentos se almacenan como JSON estructurado con campos tipados. Cada mutación se rastrea a través de un registro de transacciones, así que obtienes historial completo de versiones por defecto. La sincronización en tiempo real usa una arquitectura basada en listeners (descrita en los docs de arquitectura de Sanity en GitHub) que envía cambios a todos los suscriptores mediante observables de RxJS.

¿En qué se diferencia esto de, digamos, una base de datos PostgreSQL con una API REST? El Content Lake gestiona el modelado de contenido, el control de acceso, el caché CDN, las transformaciones de imágenes y la colaboración en tiempo real como un único servicio administrado. No corres migraciones. No gestionas réplicas. Solo defines schemas y consultas contenido.

Sanity Studio: Tu Editor Personalizable

Sanity Studio es una aplicación React de código abierto que sirve como tu interfaz de edición. No es un panel de administración hospedado — es una app React que vive en tu código. Puedes personalizar cada aspecto: componentes de entrada personalizados, campos condicionales, acciones de documentos, patrones de structure builder y plugins.

La colaboración en tiempo real está integrada. Varios editores pueden trabajar en el mismo documento simultáneamente con indicadores de presencia y actualizaciones en vivo. Si has usado Google Docs, la experiencia es similar — ves los cursores y cambios de otras personas en tiempo real.

Desplegamos nuestro Studio con npx sanity deploy, que lo hospeda en el CDN de Sanity en un subdominio personalizado. También puedes auto-hospedarlo ya que es solo una app React. Clasificamos a Sanity muy alto en nuestra comparación de CMS headless principalmente por la flexibilidad de Studio.

Cómo Configurar un Proyecto de Sanity

Para configurar Sanity CMS, instala el CLI con npm create sanity@latest, elige una plantilla de proyecto, configura tus archivos de schema y ejecuta npx sanity dev para lanzar Studio localmente. Todo el proceso toma menos de 5 minutos.

Requisitos Previos e Instalación

Necesitas Node.js 18+ y npm (o pnpm). Eso es todo. Ejecuta el comando de init:

bash
npm create sanity@latest

# Se te pedirá:
# - Método de login (Google, GitHub, email)
# - Nombre del proyecto
# - Nombre del dataset (por defecto: "production")
# - Plantilla de proyecto (blog, ecommerce, clean)
# - ¿TypeScript? (recomendado: sí)

El CLI crea la estructura del proyecto con todo lo que necesitas. Así se ve la estructura:

Estructura del Proyecto Explicada

text
my-sanity-project/
├── schemas/              # Tus schemas de contenido (aquí pasarás más tiempo)
│   ├── index.ts          # Registro de schemas -- importa y exporta todos los tipos
│   ├── post.ts           # Definiciones de tipos de documentos
│   └── blockContent.ts   # Configuración de texto enriquecido / Portable Text
├── sanity.config.ts      # Config principal -- plugins, estructura de Studio, dataset
├── sanity.cli.ts         # Config del CLI -- ID de proyecto, dataset
├── package.json
└── tsconfig.json

El archivo sanity.config.ts es tu punto de entrada. Aquí hay uno mínimo:

typescript
// sanity.config.ts
import { defineConfig } from 'sanity'
import { structureTool } from 'sanity/structure'
import { visionTool } from '@sanity/vision'
import { schemaTypes } from './schemas'

export default defineConfig({
  name: 'default',
  title: 'My Blog',
  projectId: 'your-project-id',
  dataset: 'production',
  plugins: [structureTool(), visionTool()],
  schema: { types: schemaTypes },
})

El plugin visionTool() te da un playground de GROQ dentro de Studio — lo usarás constantemente durante el desarrollo.

Desplegando tu Studio

Lanza localmente con npx sanity dev (corre en localhost:3333). Cuando estés listo para compartir con editores, despliega al CDN de Sanity:

bash
npx sanity deploy
# Pide un nombre de host, por ejemplo, "my-blog"
# Despliega a https://my-blog.sanity.studio

Consejo pro: ejecuta npx sanity@latest schema deploy después de cualquier cambio de schema. Esto sube tu schema a la API de Sanity, lo que activa características como la API de GraphQL y herramientas con conciencia de schema (incluido el servidor MCP que veremos más adelante).

Diseño de Schemas en Sanity CMS

Los schemas de Sanity se definen como objetos JavaScript o TypeScript en tu código. Cada schema especifica un tipo de documento con campos, reglas de validación y componentes de entrada personalizados. Los cambios a los schemas son instantáneos — no se necesitan migraciones de base de datos. Este es el enfoque "schema-as-code", y fue lo que nos convenció de elegir Sanity sobre Contentful.

Tipos de Campos y Validación

Sanity trae un conjunto rico de tipos de campos. Estos son los que más usamos:

Tipo de campoCaso de usoEjemplo
stringTexto corto, títulos, slugsTítulo del post, nombre del autor
textTexto plano multilíneaExtractos, descripciones
numberEnteros, decimalesTiempo de lectura, orden
booleanTogglesFlag destacado, estado de borrador
arrayListas, texto enriquecido (Portable Text)Cuerpo del contenido, etiquetas
referenceEnlaces a otros documentosAutor, categoría
imageImágenes con metadatosImagen de portada con alt text
slugCadenas URL-friendlyAuto-generadas desde el título
objectGrupos de campos anidadosCampos SEO (metaTitle + metaDescription)
date / datetimeFechasFecha de publicación

Cada campo soporta validación mediante un callback validation. Puedes aplicar campos requeridos, valores mínimos/máximos, patrones regex y reglas personalizadas:

typescript
defineField({
  name: 'seoDescription',
  title: 'Meta Description',
  type: 'string',
  validation: (Rule) =>
    Rule.required()
      .min(145)
      .max(160)
      .warning('Meta description should be 145-160 characters'),
})

Tipos de Bloque Personalizados (Nuestros Ejemplos de Producción)

Aquí es donde Sanity se pone interesante — y donde ninguna de las 6 guías de la competencia muestra código. En nuestro schema de producción, definimos cinco tipos de bloque personalizados dentro del array body: block (texto estándar), table, codeBlock, chartBlock e inlineImage.

Aquí está nuestra definición de codeBlock:

typescript
// schemas/objects/codeBlock.ts
import { defineType } from 'sanity'

export const codeBlock = defineType({
  name: 'codeBlock',
  title: 'Code Block',
  type: 'object',
  fields: [
    {
      name: 'language',
      title: 'Language',
      type: 'string',
      options: {
        list: [
          { title: 'JavaScript', value: 'javascript' },
          { title: 'TypeScript', value: 'typescript' },
          { title: 'Python', value: 'python' },
          { title: 'Bash', value: 'bash' },
          { title: 'JSON', value: 'json' },
          { title: 'GROQ', value: 'groq' },
        ],
      },
    },
    {
      name: 'code',
      title: 'Code',
      type: 'text',
    },
  ],
})

Y así referencia el campo body todos nuestros tipos personalizados juntos:

typescript
// schemas/fields/body.ts
defineField({
  name: 'body',
  title: 'Body',
  type: 'array',
  of: [
    { type: 'block' },         // Portable Text estándar (párrafos, headings, listas)
    { type: 'table' },         // Plugin @sanity/table
    { type: 'codeBlock' },     // Nuestro bloque de código personalizado
    { type: 'chartBlock' },    // Visualización de datos (barra, línea, circular)
    { type: 'inlineImage' },   // Imágenes con alt text y pies de foto
  ],
})

Esto le da a nuestros editores un conjunto de herramientas de contenido rico, manteniendo cada elemento tipado y consultable. Un chartBlock no es solo un embed de HTML opaco — son datos estructurados con campos chartType, title, dataPoints y dataLabels. Eso importa cuando intentas renderizar el mismo contenido en web, email y móvil.

Mejores Prácticas para Organizar Schemas

Mantén los schemas modulares. Nosotros los dividimos en archivos por tipo: schemas/documents/post.ts, schemas/objects/codeBlock.ts, schemas/objects/chartBlock.ts. Impórtalos todos en schemas/index.ts:

typescript
// schemas/index.ts
import { post } from './documents/post'
import { codeBlock } from './objects/codeBlock'
import { chartBlock } from './objects/chartBlock'
import { inlineImage } from './objects/inlineImage'

export const schemaTypes = [post, codeBlock, chartBlock, inlineImage]

El insight clave que obtuvimos al trabajar con contenido estructurado: tu schema ES tu modelo de contenido. Si lo piensas como context engineering para tu equipo de contenido, tomarás mejores decisiones de diseño. Cada campo que agregas debe tener un propósito — ya sea para editores, para renderizado o para consultas.

GROQ: El Lenguaje de Consulta de Sanity

GROQ (Graph-Relational Object Queries) es el lenguaje de consulta open source de Sanity para filtrar, unir y proyectar documentos JSON. La sintaxis básica es *[filter]{projection} — selecciona todos los documentos que coincidan con un filtro, luego da forma al output. Es más conciso que GraphQL para consultas específicas de Sanity y, en nuestra experiencia, más rápido de aprender.

Consultas Básicas: Filtrar y Proyectar

La consulta más simple obtiene todos los documentos de un tipo:

groq
// Obtener todos los posts -- solo título y slug
*[_type == "post"]{
  title,
  "slug": slug.current
}

// Filtrar por idioma, expandir referencia de autor
*[_type == "post" && language == "en"]{
  title,
  "slug": slug.current,
  "authorName": author->name,
  "authorImage": author->image,
  "categoryTitle": category->title,
  publishedAt
}

El operador -> sigue referencias. author->name significa "sigue la referencia del autor y devuelve el campo name". Sin consultas separadas, sin problemas N+1, sin JOINs — todo en una sola expresión.

Joins, Ordenamiento y Paginación

Para nuestras páginas de índice del blog, necesitamos posts ordenados y paginados con referencias expandidas:

groq
// Posts paginados con metadatos completos
*[_type == "post" && language == "en"] | order(publishedAt desc) [0...10] {
  title,
  "slug": slug.current,
  excerpt,
  publishedAt,
  readTime,
  "author": author->{name, image},
  "category": category->{title, "slug": slug.current},
  "coverImage": coverImage{
    "src": asset->url,
    alt
  }
}

[0...10] da los primeros 10 resultados (indexado en 0, fin exclusivo). | order(publishedAt desc) ordena del más nuevo al más antiguo. La proyección da forma al output para incluir exactamente lo que tu frontend necesita — nada más.

Puedes probar todas estas consultas de manera interactiva usando el plugin Vision dentro de Sanity Studio. Es invaluable durante el desarrollo. Para más patrones, revisa la hoja de referencia de GROQ.

GROQ vs GraphQL

Sanity soporta tanto GROQ como GraphQL. ¿Cuándo usar cada uno?

GROQ es el lenguaje nativo de Sanity. Maneja joins, proyecciones y campos calculados en una sola cadena de consulta. Es para lo que el Content Lake está optimizado.

GraphQL está disponible después de desplegar tu schema (npx sanity@latest schema deploy). Úsalo cuando necesites herramientas estandarizadas — por ejemplo, si tu frontend ya usa Apollo Client o si tu equipo conoce GraphQL pero no GROQ.

Nosotros usamos GROQ exclusivamente. Es más expresivo para datos de Sanity, y el plugin Vision hace que depurar consultas sea trivial.

Portable Text: Contenido Enriquecido Bien Hecho

Portable Text es la especificación de Sanity para texto enriquecido estructurado. En vez de almacenar contenido como cadenas HTML, almacena un array de bloques tipados — párrafos, headings, imágenes, fragmentos de código, tablas — cada uno como un objeto JSON. Esto hace que el contenido sea renderizable en cualquier framework, cualquier plataforma, cualquier formato.

La Estructura de Datos

Así se ve un párrafo y un bloque de código como JSON de Portable Text:

json
[
  {
    "_type": "block",
    "_key": "a1b2c3",
    "style": "normal",
    "markDefs": [],
    "children": [
      {
        "_type": "span",
        "_key": "d4e5f6",
        "text": "Here's an example of our pipeline config:",
        "marks": []
      }
    ]
  },
  {
    "_type": "codeBlock",
    "_key": "g7h8i9",
    "language": "typescript",
    "code": "export default defineConfig({ ... })"
  }
]

Cada bloque tiene un _type y un _key. Los bloques de texto estándar usan "block" con spans hijo (que soportan marks como negrita, cursiva y enlaces). Los bloques personalizados — como nuestros codeBlock, chartBlock, table e inlineImage — usan su propio _type y llevan campos estructurados.

¿Por qué importa esto? Porque HTML es un formato de renderizado, no de almacenamiento. Si guardas <h2>Título</h2><p>Algo de <strong>texto</strong></p> en tu base de datos, te has atado al renderizado web. No puedes extraer eso limpiamente para una app móvil, un boletín de email, un PDF o la ventana de contexto de un agente de IA. Portable Text separa el contenido de la presentación. La especificación de Portable Text es open source — no es un bloqueo de Sanity.

Bloques Personalizados en Producción

Nuestro pipeline convierte Markdown a Portable Text usando un script de Python (scripts/md_to_portable_text.py). El convertidor maneja bloques estándar, más nuestros cuatro tipos personalizados:

  • table — usa el schema del plugin @sanity/table. Filas y celdas almacenadas como datos estructurados.
  • codeBlock — lenguaje y código como campos separados, lo que permite resaltado de sintaxis en el renderizado.
  • chartBlock — tipo de gráfico, título, etiquetas de ejes, nombres de series y puntos de datos como JSON estructurado. El frontend los renderiza con Chart.js.
  • inlineImage — alt text, fuente y pie de foto opcional como campos separados.

Esta estructura significa que podemos consultar todos los ejemplos de código de nuestro blog (*[body[]._type == "codeBlock"]), encontrar posts con gráficos, o extraer todas las imágenes con alt text faltante — todo a través de GROQ.

Renderizando Portable Text

En el frontend, usa @portabletext/react (o los equivalentes de Svelte/Vue). Registras componentes personalizados para cada tipo de bloque:

tsx
import { PortableText } from '@portabletext/react'

const components = {
  types: {
    codeBlock: ({ value }) => (
      <pre className={`language-${value.language}`}>
        <code>{value.code}</code>
      </pre>
    ),
    chartBlock: ({ value }) => <Chart data={value} />,
    inlineImage: ({ value }) => (
      <figure>
        <img src={value.src} alt={value.alt} />
        {value.caption && <figcaption>{value.caption}</figcaption>}
      </figure>
    ),
  },
}

// En tu componente:
<PortableText value={post.body} components={components} />

Ese es el pipeline completo de renderizado. El componente PortableText maneja los bloques estándar (párrafos, headings, listas, marks) automáticamente. Solo defines componentes personalizados para tus tipos personalizados.

Contenido Multilingüe con Sanity CMS

Sanity soporta contenido multilingüe mediante localización a nivel de documento (documentos separados por idioma vinculados por una referencia canónica) o localización a nivel de campo (campos traducidos dentro de un documento). La localización a nivel de documento funciona mejor para SEO y publicación a gran escala — eso es lo que usamos en nuestro pipeline de 10 idiomas.

Localización a Nivel de Documento vs. a Nivel de Campo

AspectoNivel de documentoNivel de campo
EnfoqueDocumento separado por idiomaTodas las traducciones en un documento
SEOCada documento tiene su propia URL/slugURL única, más difícil servir páginas por idioma
Complejidad de consultaFiltros simples: language == "de"Acceso a campos anidados: title.de
Tamaño del contenidoDocumentos pequeños y enfocadosUn documento grande con todos los idiomas
Ideal paraPosts de blog, páginas, contenido SEOCadenas de UI, etiquetas, metadatos
Nuestro veredictoUsamos esto para todoSolo para cadenas de UI compartidas

Elegimos localización a nivel de documento porque cada traducción obtiene su propio slug, su propia URL y sus propios metadatos. La versión en turco de un post sobre Supabase vs Firebase obtiene el slug supabase-firebase-karsilastirma — turco propio, no un hack de parámetro de URL.

Nuestra Arquitectura de Pipeline de 10 Idiomas

Así funciona nuestro pipeline automatizado: escribimos un post en inglés, luego lo traducimos a 9 idiomas adicionales (alemán, francés, neerlandés, español, turco, italiano, sueco, noruego, árabe). Cada traducción pasa por conversión de Markdown, generación de Portable Text y publicación vía API de Sanity.

La arquitectura se ve así:

  1. Escribir — Markdown en inglés con frontmatter YAML
  2. Traducir — Traducción con IA a 9 idiomas (verificada por completitud y diacríticos)
  3. Convertir — Script de Python convierte cada archivo .md a JSON de Portable Text
  4. Publicar — Llamadas API a Sanity: crear documento, subir imágenes, parchear referencias

Cada documento tiene un campo language y una referencia canonicalPost que apunta al original en inglés. Aquí está la consulta GROQ para obtener un post y todas sus traducciones:

groq
// Obtener un post y todas sus traducciones
*[_type == "post" && slug.current == "sanity-cms-guide" && language == "en"][0]{
  title,
  language,
  "translations": *[
    _type == "post" &&
    canonicalPost._ref == ^._id
  ]{
    title,
    language,
    "slug": slug.current
  }
}

El lado del schema es sencillo — un campo language con un enum de idiomas soportados:

typescript
defineField({
  name: 'language',
  title: 'Language',
  type: 'string',
  options: {
    list: [
      { title: 'English', value: 'en' },
      { title: 'German', value: 'de' },
      { title: 'French', value: 'fr' },
      { title: 'Dutch', value: 'nl' },
      { title: 'Spanish', value: 'es' },
      { title: 'Turkish', value: 'tr' },
      { title: 'Italian', value: 'it' },
      { title: 'Swedish', value: 'sv' },
      { title: 'Norwegian', value: 'no' },
      { title: 'Arabic', value: 'ar' },
    ],
  },
  validation: (Rule) => Rule.required(),
})

Un gotcha que aprendimos de la manera difícil: publica el documento en inglés primero, luego parchea las referencias canonicalPost en las traducciones usando el ID del documento publicado — no el prefijo drafts.. Sanity trata los documentos borrador y publicados como entidades separadas internamente.

Para más detalles sobre cómo este pipeline se conecta al Model Context Protocol, consulta la siguiente sección.

Funciones de IA de Sanity: MCP, Canvas y Agent Context

Sanity se posiciona como el sistema operativo de contenido para la era de la IA. Las principales funciones de IA incluyen un servidor MCP para que los agentes de IA lean y escriban contenido, Canvas para edición asistida por IA dentro de Studio, y Agent Context para que los agentes de IA en producción consulten contenido estructurado con conciencia de schema.

Integración con el Servidor MCP

El servidor MCP de Sanity permite que agentes de IA — Claude Code, Cursor, Windsurf y otros — interactúen con tu workspace de Sanity de manera programática. Los agentes pueden leer schemas, ejecutar consultas GROQ, crear documentos y gestionar contenido sin envoltorios de API personalizados.

Usamos el servidor MCP de Sanity diariamente en nuestro pipeline de contenido. Nuestros agentes de IA consultan el schema para entender la estructura de documentos, buscan posts existentes para encontrar oportunidades de enlaces internos y publican nuevos documentos. El protocolo MCP le da a los agentes conciencia de schema — saben qué campos existen, qué tipos esperan y qué reglas de validación aplican. Si estás construyendo agentes de IA para empresas, este es un patrón poderoso.

Agent Context para IA en Producción

Agent Context es una función separada para integraciones de IA de nivel productivo. A diferencia del servidor MCP (diseñado para herramientas de desarrollo), Agent Context proporciona acceso de solo lectura y con alcance limitado para agentes de IA que necesitan consultar tu contenido en tiempo de ejecución — piensa en chatbots, motores de recomendación o sistemas de personalización de contenido.

La diferencia importa: MCP es para flujos de trabajo editoriales y de construcción (herramientas de desarrollo con conciencia de schema), mientras que Agent Context es para acceso a contenido en tiempo de ejecución con autenticación y limitación de velocidad adecuadas.

El contenido estructurado de Sanity le da una ventaja real aquí. Un sitio de WordPress almacena contenido como blobs de HTML — un agente de IA tiene que parsear HTML para entender el contenido. Sanity almacena documentos JSON tipados con schemas definidos. Un agente puede consultar *[_type == "product" && category == "electronics"]{name, price, features} y obtener datos limpios y estructurados de vuelta. Sin scraping, sin parseo, sin adivinar.

Cómo Usamos Sanity en Techsy

Esta no es una sección hipotética. Corremos Sanity CMS en 4 sitios web de producción, publicando en 10 idiomas con un pipeline automatizado que construimos durante el último año. Aquí está la arquitectura.

Nuestra Arquitectura de Pipeline de Contenido

El pipeline va desde la investigación hasta el post publicado en los 10 idiomas:

  1. Investigación — análisis de keywords, identificación de brechas de competidores, patrones SERP
  2. Brief — especificación de escritura estructurada con guía por sección, conteos de palabras, enlaces internos
  3. Escribir — producir Markdown en inglés con frontmatter YAML
  4. Convertir — script de Python transforma Markdown a JSON de Portable Text con nuestros 5 tipos de bloque personalizados
  5. Publicar — llamadas API a Sanity: documento createOrReplace, subir imágenes al CDN de Sanity, parchear referencias de autor/categoría
  6. Traducir — traducción con IA a 9 idiomas, verificada por completitud
  7. Publicar traducciones — mismo flujo de convertir/publicar por idioma, con referencia canonicalPost parcheada al original en inglés

El schema personalizado soporta los tipos block, table, codeBlock, chartBlock e inlineImage — todos definidos como objetos de schema de Sanity en producción con reglas de validación. Entre las herramientas de IA para startups que hemos probado, este pipeline basado en Sanity ha sido el más confiable para contenido estructurado a escala.

Lecciones de 400+ Piezas Publicadas

Algunas cosas que ojalá alguien nos hubiera dicho:

El orden de parcheo de referencias importa. Las referencias de Sanity no pueden apuntar a documentos que aún no existen. Publica el post en inglés primero, luego crea las traducciones con canonicalPost apuntando al ID publicado del documento en inglés. Lo rompimos varias veces al principio.

El despliegue de schema es por workspace. Si corres múltiples proyectos de Sanity (nosotros corremos 4), necesitas desplegar schemas a cada uno por separado: npx sanity@latest schema deploy por config de proyecto.

El plan gratuito es real. Corrimos dos de nuestros cuatro sitios en el plan gratuito durante meses. 20 usuarios, 500K solicitudes API/mes, 100K solicitudes CDN — eso es suficiente para un sitio de producción real, no solo un proyecto de prueba.

La conversión de Portable Text es el cuello de botella. Markdown a Portable Text no es trivial. Listas anidadas, tablas dentro de blockquotes, bloques de código con caracteres especiales — hay casos extremos por todos lados. Hemos iterado en nuestro script convertidor durante meses.

¿Necesitas ayuda configurando Sanity para tu proyecto? Hemos construido pipelines de contenido multilingüe para 4 sitios en producción. Obtén una consulta gratuita

Precios de Sanity CMS

Sanity ofrece tres planes: Free (20 usuarios, 500K solicitudes API/mes), Growth ($15/usuario/mes con roles avanzados y borradores programados) y Enterprise (precios personalizados con SLA y funciones de cumplimiento). El plan gratuito es el más generoso del mercado de CMS headless.

CaracterísticaFreeGrowth ($15/usuario/mes)Enterprise
Usuarios2050Ilimitados
Solicitudes API500K/mes2,5M/mesPersonalizado
Solicitudes CDN100K/mes500K/mesPersonalizado
RolesSolo AdminAdmin, Developer, Editor, ContributorRoles personalizados
ColaboraciónEdición en tiempo real+ Publicación programada, borradores+ Flujos de trabajo
SoporteComunidadEmailDedicado + SLA
Cumplimiento----SOC 2, HIPAA

En el plan gratuito, corremos dos de nuestros sitios sin alcanzar los límites. El plan Growth a $15/usuario/mes agregó acceso basado en roles (importante una vez que tuvimos editores no técnicos) y publicación programada. Los Viewers son gratuitos en Growth, lo cual es un detalle interesante — no eres penalizado por darle acceso de lectura a stakeholders.

¿Cómo se compara con los competidores?

CaracterísticaSanity FreeContentful FreeStrapi Cloud FreePayload Cloud
Usuarios20111
Tipos de contenidoIlimitados48IlimitadosIlimitados
Llamadas API500K/mesIncluidasIncluidasIncluidas
Tipos personalizadosLimitados
Precio para crecer$15/usuario/mes$300/mes$29/mes$50/mes

El plan gratuito de 20 usuarios de Sanity es excepcional. Contentful te limita a 1 usuario en el plan gratuito y salta a $300/mes para su plan Team. Si eres una startup o un equipo pequeño, el plan gratuito de Sanity te permite correr cargas de trabajo de producción reales sin gastar nada.

Sanity también ofrece un programa para startups que les da a las startups elegibles un año de acceso gratuito al plan Growth. Vale la pena postular si calificas.

Preguntas Frecuentes

¿Qué es Sanity CMS y cómo funciona?

Sanity CMS es una plataforma de contenido headless que almacena documentos JSON estructurados en un backend administrado llamado Content Lake. Editas contenido a través de Sanity Studio (una app React personalizable), lo consultas con GROQ o GraphQL, y lo renderizas en cualquier framework frontend. El contenido se sincroniza en tiempo real entre todos los clientes conectados.

¿Es gratuito Sanity CMS?

Sí. El plan gratuito de Sanity incluye 20 usuarios, 500K solicitudes API por mes y 100K solicitudes CDN — el plan gratuito más generoso entre las plataformas CMS headless. El plan Growth cuesta $15 por usuario por mes y agrega acceso basado en roles, publicación programada y límites más altos. Los precios Enterprise son personalizados.

¿Cuál es la diferencia entre Sanity y Contentful?

Sanity usa schema-as-code (los schemas viven en tu código), GROQ para consultas y un Studio open source completamente personalizable. Contentful usa modelado de contenido basado en GUI, GraphQL y un editor hospedado con menos personalización. El plan gratuito de Sanity incluye 20 usuarios frente a 1 de Contentful. Contentful tiene un marketplace de plugins más grande.

¿Es Sanity CMS bueno para principiantes?

Sanity Studio es intuitivo para editores de contenido — la experiencia de edición no requiere conocimientos técnicos. Sin embargo, configurar schemas requiere dominio de JavaScript o TypeScript. Sanity ofrece excelente documentación, plantillas de proyecto y un Slack comunitario con soporte activo. Empieza con npm create sanity@latest y una plantilla de blog.

¿Puedo auto-hospedar Sanity?

Sanity Studio es completamente auto-hospedable porque es una aplicación React open source. Puedes desplegarlo en Vercel, Netlify o cualquier proveedor de hosting estático. El backend del Content Lake es un servicio administrado — no hay opción de auto-hospedaje para la capa de datos. Este es un trade-off: obtienes cero gestión de infraestructura pero ningún control de datos on-premises.

¿Qué tipo de base de datos usa Sanity?

El Content Lake de Sanity no es una base de datos SQL o NoSQL tradicional. Es un almacén de documentos administrado que guarda contenido como JSON estructurado con una capa de consultas GROQ encima. No interactúas con la base de datos subyacente directamente — interactúas a través de las APIs de Sanity. Los documentos tienen historial completo de versiones y sincronización en tiempo real integrados.

¿Es Sanity CMS open source?

Sanity Studio es open source bajo la licencia MIT — puedes forkearlo, personalizarlo y auto-hospedarlo. El backend del Content Lake es SaaS propietario. La especificación del lenguaje de consulta GROQ también es open source, publicada en GitHub. La especificación de Portable Text también es open source, mantenida en portabletext.org.

¿Qué es Portable Text en Sanity?

Portable Text es la especificación de Sanity para texto enriquecido estructurado. En vez de almacenar contenido como cadenas HTML, representa párrafos, headings, imágenes y bloques personalizados como objetos JSON tipados en un array. Esto hace que el contenido sea portable entre frameworks y plataformas. Puedes definir tipos de bloque personalizados como fragmentos de código, gráficos y tablas con sus propios campos estructurados.

¿Qué es GROQ y en qué se diferencia de GraphQL?

GROQ (Graph-Relational Object Queries) es el lenguaje de consulta nativo de Sanity. Su sintaxis — *[filter]{projection} — es más concisa que GraphQL para datos de Sanity, con soporte integrado para joins mediante el operador -> y campos calculados. GraphQL también está disponible para equipos que prefieren herramientas estandarizadas o que ya usan Apollo Client.

¿Cómo maneja Sanity el contenido multilingüe?

Sanity soporta localización a nivel de documento (documentos separados por idioma vinculados por referencias canónicas) y localización a nivel de campo (campos traducidos dentro de un documento). La localización a nivel de documento es mejor para SEO porque cada traducción obtiene su propia URL y metadatos. Usamos localización a nivel de documento para publicar en 10 idiomas con pipelines automatizados de traducción y publicación.

Etiquetas

sanity-cmsheadless-cmsgroqportable-textgestión-de-contenido

Compartir este artículo

Inicia Tu Proyecto

¿Listo para construir algo extraordinario?

Convirtamos tu visión en realidad. Nuestro equipo está listo para ayudarte a crear software que marque la diferencia.