Diil Docs
  1. Documentación
  2. Referencia de la API

GET /v1/langs — idiomas del sitio

Actualizado:

El endpoint más pequeño de la API y el que tu selector de idioma llevaba tiempo esperando. Responde a una sola pregunta, “¿qué idiomas habla este sitio ahora mismo?”, y lo hace exactamente en el orden en que tus editores los colocaron en el CRM.

Tira de él cuando necesites:

  • pintar un selector de idioma en la cabecera sin hardcodear en y de en cinco sitios distintos;
  • comprobar que el idioma de la URL (/de/pricing) existe de verdad antes de pasarlo a ?lang;
  • generar rutas localizadas, etiquetas hreflang o un sitemap por idioma.

Listar los idiomas activos

GET/v1/langs

https://back.sitecog.com/content/v1/langs

Devuelve los idiomas activos del sitio como un array, ordenados igual que en el CRM. Los idiomas desactivados no aparecen: si un código no está en esta lista, la API tampoco lo aceptará en ?lang.

Parámetros

Aquí no hay nada que ajustar: ni parámetros de ruta ni parámetros de query. Solo la clave.

x-crm-keyheaderstringobligatorio
La clave de tu sitio. Cada clave está ligada a un sitio, así que la respuesta siempre son los idiomas de ese sitio. También se puede pasar como ?key= si no puedes usar cabeceras. Mira Claves del sitio.

Ejemplo de petición

curl https://back.sitecog.com/content/v1/langs \
  -H "x-crm-key: pk_3f9c2a7e1b4d4c0e8a6f5b2d9c1e7a40"

Ejemplo de respuesta

200 OKjson
[
  { "key": "en", "title": "English", "index": 0 },
  { "key": "de", "title": "German", "index": 1 }
]

Campos de la respuesta

Un array de objetos, uno por cada idioma activo. Tres campos cada uno: ya te dijimos que era pequeño.

keystring
Código de idioma: dos letras minúsculas (en, de) o una variante regional como pt-BR. Es justo el valor que pasas en ?lang. Distingue mayúsculas: pt-BR y pt-br son códigos distintos.
titlestring
El nombre del idioma tal como lo escribió el editor en el CRM. ¿Quieres que el selector diga “Deutsch” en vez de “German”? Renómbralo en el CRM, sin deploy.
indexnumber
Posición en el CRM, empezando por 0. El array ya llega ordenado por este campo, así que casi nunca tendrás que ordenarlo tú.

Un selector de idioma en React

El montaje habitual: el idioma vive en la URL (/en/…, /de/…), el selector se construye a partir de /v1/langs y cada petición de contenido lleva el mismo código en ?lang. Aquí tienes un selector que no sabe nada de idiomas concretos: añade el italiano en el CRM mañana y aparecerá sin más.

components/LangSwitcher.tsxtsx
type Lang = { key: string; title: string; index: number };

export function LangSwitcher({ langs, current, path }: {
  langs: Lang[];      // directamente de GET /v1/langs
  current: string;    // el idioma de la página que se muestra
  path: string;       // el resto de la URL, p. ej. "/pricing"
}) {
  return (
    <nav aria-label="Language">
      {langs.map((lang) => (
        <a
          key={lang.key}
          href={`/${lang.key}${path}`}
          hrefLang={lang.key}
          aria-current={lang.key === current ? 'true' : undefined}
        >
          {lang.title}
        </a>
      ))}
    </nav>
  );
}

Cómo combinarlo con ?lang

La clave que obtienes aquí es la misma que envías en todas partes. Compara primero el código de la URL con la lista: un código desconocido en ?lang es un 400 unknown_lang, y nadie quiere una página de error porque alguien escribió /fr/ a mano.

app/[lang]/page.tsxtsx
import { notFound } from 'next/navigation';
import { getLangs } from '@/lib/langs';
import { LangSwitcher } from '@/components/LangSwitcher';

export default async function Home({ params }: { params: Promise<{ lang: string }> }) {
  const { lang } = await params;
  const langs = await getLangs();

  // Idioma desconocido en la URL → un 404 normal en vez de un 400 de la API
  if (!langs.some((l) => l.key === lang)) notFound();

  const res = await fetch(`https://back.sitecog.com/content/v1/pages/home?lang=${lang}`, {
    headers: { 'x-crm-key': process.env.CRM_KEY! },
    next: { revalidate: 60 },
  });
  const page = await res.json();

  return (
    <>
      <LangSwitcher langs={langs} current={lang} path="" />
      <h1>{page.content.hero.content.hero_title.content[lang]}</h1>
    </>
  );
}

¿Necesitas un idioma por defecto para quien entra en /? Eso lo decides tú: muchas webs simplemente toman el primero de la lista. La API nunca elige un idioma por ti ni sustituye una traducción que falta; cómo gestionar esos huecos con elegancia lo cuenta Idiomas y fallbacks.

Errores

EstadoCuerpoQué ha pasado
401{"message":"invalid_key"}Falta la clave, está mal formada o se ha revocado.
405{"message":"method_not_allowed"}Solo se aceptan GET (y HEAD). La API es de solo lectura.
429{"message":"rate_limit_exceeded"}Demasiadas peticiones en este minuto. Mira Límites de peticiones.

La lista completa, con soluciones, está en la página de Errores.

Consejos desde la trinchera