Kontent.ai y Astro
Kontent.ai es un CMS headless que te permite gestionar el contenido de forma estructurada y modular, con el apoyo de funciones de IA.
Integración con Astro
Sección titulada "Integración con Astro"En esta sección, utilizarás el SDK de TypeScript de Kontent.ai para conectar tu proyecto de Kontent.ai a tu aplicación de Astro.
Requisitos previos
Sección titulada “Requisitos previos”Para empezar, necesitarás lo siguiente:
-
Proyecto de Kontent.ai - Si aún no tienes una cuenta de Kontent.ai, regístrate gratis y crea un nuevo proyecto.
-
Claves de API de Delivery - Necesitarás el Environment ID para el contenido publicado y la clave de API de Preview para obtener borradores (opcional). Ambas claves se encuentran en la pestaña Environment Settings -> API keys en Kontent.ai.
Configuración de credenciales
Sección titulada "Configuración de credenciales"Para añadir tus credenciales de Kontent.ai a Astro, crea un archivo .env en la raíz de tu proyecto con las siguientes variables:
KONTENT_ENVIRONMENT_ID=YOUR_ENVIRONMENT_IDKONTENT_PREVIEW_API_KEY=YOUR_PREVIEW_API_KEYAhora, estas variables de entorno se pueden usar en tu proyecto de Astro.
Si deseas obtener IntelliSense de TypeScript para estas variables de entorno, puedes crear un nuevo archivo env.d.ts en el directorio src/ y configurar ImportMetaEnv de esta manera:
interface ImportMetaEnv { readonly KONTENT_ENVIRONMENT_ID: string; readonly KONTENT_PREVIEW_API_KEY: string;}Tu directorio raíz ahora debería incluir estos nuevos archivos:
Directoriosrc/
- env.d.ts
- .env
- astro.config.mjs
- package.json
Instalación de dependencias
Sección titulada "Instalación de dependencias"Para conectar Astro con tu proyecto de Kontent.ai, instala el SDK de TypeScript de Kontent.ai:
npm install @kontent-ai/delivery-sdk pnpm add @kontent-ai/delivery-sdk yarn add @kontent-ai/delivery-sdkA continuación, crea un nuevo archivo llamado kontent.ts en el directorio src/lib/ de tu proyecto de Astro.
import { createDeliveryClient } from "@kontent-ai/delivery-sdk";
export const deliveryClient = createDeliveryClient({ environmentId: import.meta.env.KONTENT_ENVIRONMENT_ID, previewApiKey: import.meta.env.KONTENT_PREVIEW_API_KEY,});Lee más sobre cómo obtener variables de entorno en Astro.
Esta implementación crea un nuevo objeto DeliveryClient utilizando las credenciales del archivo .env.
La previewApiKey es opcional. Cuando se utiliza, puedes configurar cada consulta al endpoint de la API de Delivery para que devuelva las versiones más recientes de los elementos de contenido, independientemente de su estado en el flujo de trabajo. De lo contrario, solo se devuelven los elementos publicados.
Finalmente, el directorio raíz de tu proyecto de Astro ahora debería incluir estos nuevos archivos:
Directoriosrc/
Directoriolib/
- kontent.ts
- env.d.ts
- .env
- astro.config.mjs
- package.json
Obtención de datos
Sección titulada "Obtención de datos"El DeliveryClient ahora está disponible para todos los componentes. Para obtener contenido, usa el DeliveryClient y el encadenamiento de métodos para definir los elementos que deseas. Este ejemplo muestra una obtención básica de publicaciones de blog y renderiza sus títulos en una lista:
---import { deliveryClient } from "../lib/kontent";
const blogPosts = await deliveryClient .items() .type("blogPost") .toPromise()---<html lang="en"> <head> <meta charset="utf-8" /> <meta name="viewport" content="width=device-width" /> <title>Astro</title> </head> <body> <ul> {blogPosts.data.items.map(blogPost => ( <li>{blogPost.elements.title.value}</li> ))} </ul> </body></html>Puedes encontrar más opciones de consulta en la documentación de Kontent.ai.
Creación de un blog con Astro y Kontent.ai
Sección titulada “Creación de un blog con Astro y Kontent.ai”Con la configuración anterior, ahora puedes crear un blog que use Kontent.ai como fuente de contenido.
Requisitos previos
Sección titulada “Requisitos previos”-
Proyecto de Kontent.ai - Para este tutorial, se recomienda utilizar un proyecto en blanco. Si ya tienes algunos tipos de contenido en tu modelo de contenido, puedes usarlos, pero necesitarás modificar los fragmentos de código para que coincidan con tu modelo de contenido.
-
Proyecto de Astro configurado para la obtención de contenido desde Kontent.ai - ver arriba para obtener más detalles sobre cómo configurar un proyecto de Astro con Kontent.ai
Configuración del modelo de contenido
Sección titulada “Configuración del modelo de contenido”En Kontent.ai, navega a Content model y crea un nuevo tipo de contenido con los siguientes campos y valores:
- Nombre: Publicación de blog
- Elements:
- Text field
- Nombre: Título
- Elemento requerido: sí
- Rich text field
- Nombre: Teaser
- Elemento requerido: sí
- Permitido en este elemento: solo marcar Texto
- Rich text field
- Nombre: Contenido
- Elemento requerido: sí
- Date & time field
- Nombre: Fecha
- URL slug field
- Nombre: Slug de URL
- Elemento requerido: sí
- Generación automática desde: selecciona “Título”
- Text field
Luego, haz clic en Save Changes.
Creación de contenido
Sección titulada "Creación de contenido"Ahora, navega a la pestaña Content & assets y crea un nuevo elemento de contenido de tipo Blog Post. Rellena los campos usando estos valores:
- Nombre del elemento de contenido: Astro
- Título: Astro es increíble
- Teaser: Astro es un framework todo en uno para construir sitios web rápidos más rápidamente.
- Contenido: Puedes usar JavaScript para implementar la funcionalidad del sitio web, pero no es necesario ningún bundle del cliente.
- Fecha y hora: selecciona hoy
- Slug de URL: astro-is-amazing
Cuando hayas terminado, publica la publicación del blog usando el botón Publish en la parte superior.
Nota: Siéntete libre de crear tantas publicaciones de blog como desees antes de pasar al siguiente paso.
Generación del modelo de contenido en TypeScript
Sección titulada “Generación del modelo de contenido en TypeScript”A continuación, generarás tipos de TypeScript a partir de tu modelo de contenido.
Este paso es opcional pero proporciona una experiencia de desarrollador mucho mejor y te permite descubrir posibles problemas en el momento de la compilación en lugar de en el tiempo de ejecución.
Primero, instala el generador de modelos JS de Kontent.ai, ts-node y dotenv:
npm install @kontent-ai/model-generator ts-node dotenv pnpm add @kontent-ai/model-generator ts-node dotenv yarn add @kontent-ai/model-generator ts-node dotenvLuego, añade el siguiente script a package.json:
{ ... "scripts": { ... "regenerate:models": "ts-node --esm ./generate-models.ts" },}Debido a que los tipos requieren información estructural sobre tu proyecto que no está disponible en la API pública, también debes agregar una clave de API de Content Management al archivo .env. Puedes generar la clave en Environment settings -> API keys -> Management API.
KONTENT_ENVIRONMENT_ID=YOUR_ENVIRONMENT_IDKONTENT_PREVIEW_API_KEY=YOUR_PREVIEW_API_KEYKONTENT_MANAGEMENT_API_KEY=YOUR_MANAGEMENT_API_KEYFinalmente, añade el script generate-models.ts que configura el generador de modelos para generar los modelos:
import { generateModelsAsync, textHelper } from '@kontent-ai/model-generator'import { rmSync, mkdirSync } from 'fs'
import * as dotenv from 'dotenv'dotenv.config()
const runAsync = async () => { rmSync('./src/models', { force: true, recursive: true }) mkdirSync('./src/models')
// change working directory to models process.chdir('./src/models')
await generateModelsAsync({ sdkType: 'delivery', apiKey: process.env.KONTENT_MANAGEMENT_API_KEY ?? '', environmentId: process.env.KONTENT_ENVIRONMENT_ID ?? '', addTimestamp: false, isEnterpriseSubscription: false, })}
// Self-invocation async function;(async () => { await runAsync()})().catch(err => { console.error(err) throw err})Ahora, ejecútalo:
npm run regenerate:models pnpm run regenerate:models yarn run regenerate:modelsMostrar una lista de publicaciones de blog
Sección titulada “Mostrar una lista de publicaciones de blog”Ahora estás listo para obtener algo de contenido. Ve a la página de Astro donde deseas mostrar una lista de todas las publicaciones de blog, por ejemplo, la página de inicio index.astro en src/pages.
Obtén todas las publicaciones de blog en el frontmatter de la página de Astro:
---import { deliveryClient } from '../lib/kontent';import type { BlogPost } from '../models';import { contentTypes } from '../models/project/contentTypes';
const blogPosts = await deliveryClient .items<BlogPost> .type(contentTypes.blog_post.codename) .toPromise()---Si te saltaste la generación del modelo, también puedes usar un objeto no tipado y una cadena literal para definir el tipo:
const blogPosts = await deliveryClient .items() .type("blogPost") .toPromise()La llamada fetch devolverá un objeto response que contiene una lista de todas las publicaciones de blog en data.items. En la sección HTML de la página de Astro, puedes usar la función map() para listar las publicaciones de blog:
---import { deliveryClient } from '../lib/kontent';import type { BlogPost } from '../models';import { contentTypes } from '../models/project/contentTypes';
const blogPosts = await deliveryClient .items<BlogPost> .type(contentTypes.blogPost.codename) .toPromise()---<html lang="en"> <head> <meta charset="utf-8" /> <meta name="viewport" content="width=device-width" /> <title>Astro</title> </head> <body> <h1>Blog posts</h1> <ul> {blogPosts.data.items.map(blogPost => ( <li> <a href={`/blog/${blogPost.elements.url_slug.value}/`} title={blogPost.elements.title.value}> {blogPost.elements.title.value} </a> </li> ))} </ul> </body></html>Generación de publicaciones de blog individuales
Sección titulada “Generación de publicaciones de blog individuales”El último paso del tutorial es generar páginas detalladas de publicaciones de blog.
Generación de sitios estáticos
Sección titulada "Generación de sitios estáticos"En esta sección, utilizarás el Modo Estático (SSG) con Astro.
Primero, crea un archivo [slug].astro en /src/pages/blog/ que debe exportar una función getStaticPaths que recopile todos los datos del CMS:
---import { deliveryClient } from '../../lib/kontent';import type { BlogPost } from '../../models';import { contentTypes } from '../../models/project/contentTypes';
export async function getStaticPaths() { const blogPosts = await deliveryClient .items<BlogPost>() .type(contentTypes.blog_post.codename) .toPromise()---Hasta ahora, la función obtiene todas las publicaciones de blog de Kontent.ai. El fragmento de código es exactamente el mismo que usaste en la página de inicio.
A continuación, la función debe exportar las rutas y los datos de cada publicación de blog. Nombraste el archivo [slug].astro, por lo que el parámetro que representa el slug de la URL se llama slug:
---import { deliveryClient } from '../../lib/kontent';import type { BlogPost } from '../../models';import { contentTypes } from '../../models/project/contentTypes';
export async function getStaticPaths() { const blogPosts = await deliveryClient .items<BlogPost>() .type(contentTypes.blog_post.codename) .toPromise()
return blogPosts.data.items.map(blogPost => ({ params: { slug: blogPost.elements.url_slug.value }, props: { blogPost } }))}---La última parte es proporcionar la plantilla HTML y mostrar cada publicación de blog:
---import { deliveryClient } from '../../lib/kontent';import type { BlogPost } from '../../models';import { contentTypes } from '../../models/project/contentTypes';
export async function getStaticPaths() { const blogPosts = await deliveryClient .items<BlogPost>() .type(contentTypes.blog_post.codename) .toPromise()
return blogPosts.data.items.map(blogPost => ({ params: { slug: blogPost.elements.url_slug.value }, props: { blogPost } }))}
const blogPost: BlogPost = Astro.props.blogPost---<html lang="en"> <head> <meta charset="utf-8" /> <meta name="viewport" content="width=device-width" /> <title>{blogPost.elements.title.value}</title> </head> <body> <article> <h1>{blogPost.elements.title.value}</h1> <Fragment set:html={blogPost.elements.teaser.value} /> <Fragment set:html={blogPost.elements.content.value} /> <time>{new Date(blogPost.elements.date.value ?? "")}</time> </body></html>Navega a tu previsualización de Astro (por defecto, http://localhost:4321/blog/astro-is-amazing/) para ver la publicación de blog renderizada.
Renderizado bajo demanda
Sección titulada "Renderizado bajo demanda"Si tus rutas se renderizan bajo demanda, utilizarás rutas dinámicas para obtener los datos de la página desde Kontent.ai.
Crea un nuevo archivo [slug].astro en /src/pages/blog/ y añade el siguiente código. La obtención de datos es muy similar a los casos de uso anteriores, pero añade un equalsFilter que nos permite encontrar la publicación de blog correcta basada en la URL utilizada:
---import { deliveryClient } from '../../lib/kontent';import type { BlogPost } from '../../models';import { contentTypes } from '../../models/project/contentTypes';
const { slug } = Astro.paramslet blogPost: BlogPost;try { const data = await deliveryClient .items<BlogPost>() .equalsFilter(contentTypes.blog_post.elements.url_slug.codename, slug ?? '') .type(contentTypes.blog_post.codename) .limitParameter(1) .toPromise() blogPost = data.data.items[0]} catch (error) { return Astro.redirect('/404')}---Si no estás usando tipos generados, puedes usar cadenas literales en su lugar para definir el tipo de elemento de contenido y el nombre en código del elemento filtrado:
const data = await deliveryClient .items() .equalsFilter("url_slug", slug ?? '') .type("blog_post") .limitParameter(1) .toPromise()Por último, añade el código HTML para renderizar la publicación de blog. Esta parte es la misma que con la generación estática:
---import { deliveryClient } from '../../lib/kontent';import type { BlogPost } from '../../models';import { contentTypes } from '../../models/project/contentTypes';
const { slug } = Astro.paramslet blogPost: BlogPost;try { const data = await deliveryClient .items<BlogPost>() .equalsFilter(contentTypes.blog_post.elements.url_slug.codename, slug ?? '') .type(contentTypes.blog_post.codename) .limitParameter(1) .toPromise() blogPost = data.data.items[0]} catch (error) { return Astro.redirect('/404')}---<html lang="en"> <head> <meta charset="utf-8" /> <meta name="viewport" content="width=device-width" /> <title>{blogPost.elements.title.value}</title> </head> <body> <article> <h1>{blogPost.elements.title.value}</h1> <Fragment set:html={blogPost.elements.teaser.value} /> <Fragment set:html={blogPost.elements.content.value} /> <time>{new Date(blogPost.elements.date.value ?? '')}</time> </body></html>Publicando tu sitio
Sección titulada "Publicando tu sitio"Para desplegar tu sitio web, visita las guías de despliegue y sigue las instrucciones para tu proveedor de alojamiento preferido.
Reconstruir al haber cambios en Kontent.ai
Sección titulada “Reconstruir al haber cambios en Kontent.ai”Si tu proyecto está utilizando el modo estático predeterminado de Astro, necesitarás configurar un webhook para activar una nueva compilación cuando cambie tu contenido. Si estás utilizando Netlify o Vercel como tu proveedor de alojamiento, puedes utilizar su función de webhook para activar una nueva compilación a partir de eventos de Kontent.ai.
Netlify
Sección titulada "Netlify"Para configurar un webhook en Netlify:
-
Ve al panel de control de tu sitio y haz clic en Build & deploy.
-
En la pestaña Continuous Deployment, busca la sección Build hooks y haz clic en Add build hook.
-
Proporciona un nombre para tu webhook y selecciona la rama en la que deseas activar la compilación. Haz clic en Save y copia la URL generada.
Para configurar un webhook en Vercel:
-
Ve al panel de control de tu proyecto y haz clic en Settings.
-
En la pestaña Git, busca la sección Deploy Hooks.
-
Proporciona un nombre para tu webhook y la rama en la que deseas activar la compilación. Haz clic en Add y copia la URL generada.
Añadir un webhook a Kontent.ai
Sección titulada “Añadir un webhook a Kontent.ai”En la aplicación de Kontent.ai, ve a Environment settings -> Webhooks. Haz clic en Create new webhook y proporciona un nombre para tu nuevo webhook. Pega la URL que copiaste de Netlify o Vercel y selecciona qué eventos deben activar el webhook. Por defecto, para reconstruir tu sitio cuando cambie el contenido publicado, solo necesitas los eventos Publish y Unpublish bajo Delivery API triggers. Cuando hayas terminado, haz clic en Save.
Ahora, cada vez que publiques una nueva publicación de blog en Kontent.ai, se activará una nueva compilación y tu blog se actualizará.
Más guías de CMS
Socios de CMS destacados
-
CloudCannon
CMS basado en Git creado para mayor velocidad, seguridad y cero dolores de cabeza.