Integrar Sanity.io en ReactJS

Empecemos por el principio, ¿qué es Sanity.io? Es un software que genera un backend dentro de tu sitio web con el que puedes gestionar los contenidos de tu blog, web corporativa o ecommerce, vamos, lo que se conoce con el nombre de CMS. Añado que es un CMS algo básico, ya que muchas personas al escuchar la palabra CMS automáticamente piensan en Wordpress.

¿Por qué me interesaría integrar Sanity en un proyecto? Es interesante porque se conecta mediante API con los principales frameworks de Frontend para hacer blogs o web corporativas como React, NextJS o VueJS, dándoles la posibilidad de editar su contenido sin tener tener conocimientos de desarrollo web.

¿Cuál es su precio? Puedes empezar con un plan gratuito que para hacer las primeras pruebas es más que suficiente y después se puede optar por un plan avanzado de 199$ por proyecto al mes o un custom según tus necesidades.

Ahora vamos a ver cómo se integra con una web hecha con ReactJS.

En primer lugar debemos instalar, crear, nuestra webapp de reactjs:

npx create-react-app my-project
cd my-project

Ahora debemos instalar el paquete de sanity/cli en nuestro equipo y para ello vamos a lanzar el siguiente comando:

npm install -g @sanity/cli

Si añades el -g en tu comando instalar el paquete de manera global.

Ahora que ya tenemos el paquete de Sanity instalado, ejecutamos el comando que inicia la creación de un nuevo proyecto en nuestro paquete de la webapp:

sanity init

Esto te pedirá que hagas login y te dará tres opciones de hacerlo, con tu cuenta de github, google o con cuenta de correo y contraseña.

Una vez hecho el login, nos preguntará si queremos usar un proyecto que ya tengamos.

Integrar Sanity.io en ReactJS 2

Si escogemos uno nuevo nos pedirá un nombre para el proyecto, después nos preguntará: Use the default dataset configuration? le indicamos que sí poniendo una Y, nos preguntará cual es la ruta para el proyecto, el path, y por último, nos dará las siguientes opciones para generar el proyecto:

Integrar Sanity.io en ReactJS 3

Con esto ya tenemos nuestro backend de Sanity preparado para conectarlo a la webapp. Si quieres levantar el proyecto de Sanity solo tiene que entrar en la carpeta de tu proyecto de sanity, por ejemplo cd mysanityproject y lanzar el siguiente comando:

sanity start

Ahora que ya tenemos todo funcionando, volvemos a nuestra carpeta de webapp, en mi caso la carpeta my-project y descargamos el paquete para el cliente de Sanity:

npm install --save @sanity/client

A continuación, creamos un fichero, yo lo he llamado sanityClient.js, dentro de la carpeta /src de nuestro proyecto con el siguiente contenido:

import sanityClient from '@sanity/client'

export default sanityClient({
    projectId: "IDPROJECT",
    dataset: "production"
})

El IDPROJECT lo encontraras en el fichero: mysanityproject/sanity.json.

Por último, en el componente en el que quieras mostrar datos de Sanity, por ejemplo todos los posts para generar un listado, debes tener un código parecido al siguiente. En los comentarios aclaro las partes de código que son necesarios para hacer la integración con Sanity:

import React, {useState, useEffect} from 'react'
import { Link } from 'react-router-dom'
// Importamos el cliente que tiene el IDProject para conectar 
// con el proyecto de Sanity
import sanityClient from '../sanityClient' 


export default function Posts() {
    const [postData, setPost] = useState(null)
    
    useEffect(() => {
        // Consultamos todos los datos, por eso el *, del tipo post y cogemos los que queremos
        sanityClient.fetch(`*[_type == "post"]{
            title,
            slug,
            mainImage{
                asset->{
                    _id,
                    url,
                },
                alt
            }
        }`).then((data) => setPost(data))
        .catch(console.error)
    }, [])
    
    return (
        <main className="bg-green-100 min-h-screen p-12">
            <section className="container mx-auto">
                <h1 className="text-5xl flex justify-center">Blog</h1>
                <h2 className="text-lg text-gray-600 flex justify-center mb-12">Welcome to my Blog Page</h2>
                <div className="grid md:grid-cols-2 lg:grid-cols-3 gap-8">
                    // Hacemos un bucle para sacar los datos que hemos traído de la api de Sanity
                    {postData && postData.map((post, index) => (
                        <article>
                            <Link to={`/post/${post.slug.current}`} key={post.slug.current}>
                                <span className="block h-64 relative rounded shadow leading-snug bg-white border-l-8 border-green-400" key={index}>
                                    <img 
                                        src={post.mainImage.asset.url}
                                        alt={post.mainImage.alt}
                                        className="w-full h-full rounded-r object-cover absolute"
                                    />
                                    <span className="block relative h-full flex justify-end items-end pr-4 pb-4">
                                        <h3 className="text-gray-800 text-lg font-bold px-3 py-4 bg-green-700 text-green-100 bg-opacity-75 rounded">{post.title}</h3>
                                    </span>
                                </span>
                            </Link>
                        </article>
                    ))}
                </div>
            </section>
        </main>
    )
}