Skip to content

Creando una app con React usando WordPress como Headless CMS

Maximo Martinez Soria

Maximo Martinez Soria

  • 4 min to read
Post thumbnail

Cada vez estamos más acostumbrados a ver interfaces complejas, dinámicas y reactivas.

Los CMS como WordPress, complican un poco la creación de este tipo de interfaces con las herramientas que proveen por default.

A partir de esto, nació el concepto de Headless CMS. Es decir, usar solamente las herramientas de carga de contenido del CMS y consumir una API para tener total libertad sobre la vista. Además, se crearon nuevos CMS que apuntan directamente a ser Headless. Algunos ejemplos son Strapi, Keystone, entre otros.

En este artículo, vamos a usar WordPress como Headless CMS, y vamos a consumir su API desde una app usando React.

Pre-requisitos

Algo que no vamos a cubrir, es la instalación de WordPress.

De todas formas, lo único que vamos a necesitar es un WordPress con algunos posts. Podés usar el plugin FakerPress para crear dummy data.

Crear proyecto React

El ecosistema de React está en constante crecimiento y ya existen muchas herramientas que simplifican cosas como Server Side Rendering o Static Site Generation. Next y Gatsby son de las más populares.

Para este ejemplo, no vamos a usar ninguna de esas herramientas, pero te recomiendo que las pruebes. Pueden llegar a ahorrar mucho tiempo.

Usemos create-react-app para traernos el scaffold y todo lo necesario para tener React funcionando.

# Crear proyecto
yarn create react-app blog

# Correr proyecto
cd blog
yarn start

Una vez tengamos el proyecto corriendo, vamos a limpiar un poco el archivo App.js.

import './App.css'

function App() {
	return <div className="App"></div>
}

export default App

Ahora sí, ya estamos listos para empezar.

Consumir WordPress API

Por default, WordPress tiene una Rest API que podemos consumir para traernos información. Si fuese necesario, también podemos crear custom endpoints para modificar la lógica.

El endpoint para traernos todos los posts es: /wp-json/wp/v2/posts.

Vamos a utilizar la Fetch API para hacerle una GET request a ese endpoint.

// En mi caso, WordPress está corriendo en http://blog.test/

// GET request
fetch('http://blog.test/wp-json/wp/v2/posts')
			// Convertimos la respuesta en JSON
			.then((response) => response.json())
			// Recibimos los posts
			.then((posts) => {
				console.log(posts)
			})

Vamos a meter ese código adentro de un useEffect para decirle a React que tiene que ejecutarlo cuando el componente se monte. Además, vamos a crear 2 estados. Uno para guardar los posts y otro para saber si la request está cargando.

import { useEffect, useState } from 'react'
import './App.css'

function App() {
	const [posts, setPosts] = useState([])
	const [isLoading, setIsLoading] = useState(false)

	/* useEffect nos permite ejecutar una función cada vez que alguna de 
		 sus dependencias cambie. Las dependencias, se especifican en el array
		 que recibe como segundo parámetro. 
		 En este caso, solo queremos que se ejecute una vez. Por eso dejamos el
		 array vacío.
	*/
	useEffect(() => {
		setIsLoading(true)
		fetch('http://blog.test/wp-json/wp/v2/posts')
			.then((response) => response.json())
			.then((posts) => {
				setPosts(posts)
				setIsLoading(false)
			})
	}, [])

	return <div className="App"></div>
}

export default App

Mostrar los posts

Por último, vamos a mostrar los posts en pantalla. Para este ejemplo simplemente vamos a mostrar el título y el contenido, pero hay mucha mas información disponible.

import { useEffect, useState } from 'react'
import './App.css'

function App() {
	const [posts, setPosts] = useState([])
	const [isLoading, setIsLoading] = useState(false)

	useEffect(() => {
		setIsLoading(true)
		fetch('http://blog.test/wp-json/wp/v2/posts')
			.then((response) => response.json())
			.then((posts) => {
				setPosts(posts)
				setIsLoading(false)
			})
	}, [])

	if (isLoading) {
		return <div>Loading...</div>
	}

	return (
		<div className="App">
			<h1>Posts</h1>

			<ul>
				{posts.map((post) => (
					<li key={post.id}>
						<article>
							<h2>{post.title.rendered}</h2>
							<div
								dangerouslySetInnerHTML={{ __html: post.content.rendered }}
							></div>
						</article>
					</li>
				))}
			</ul>
		</div>
	)
}

export default App

Mejoras

Ya lo tenemos funcionando! Estamos usando el dashboard de WordPress para crear contenido y la potencia de React para crear interfaces. Best of both worlds!

Este es un ejemplo simple que necesita varias mejoras. Te dejo algunas que se me ocurren para que las implementes:

  • Agregar un catch a la request y manejar el error en caso de que exista.
  • Convertir el article y todo lo que tiene adentro, en un componente PostCard.
  • Agregar paginación o Lazy Loading. La API de WordPress te permite pasarle un parámetro page para poder hacer esto.
  • Agregar estilos.

Dejanos el link a tu repo en los comentarios para que podamos ver como te quedó.

Maximo Martinez Soria

Maximo Martinez Soria

Software engineer with deep knowledge on web technologies and the JavaScript ecosystem. Currently spending most of my time developing web apps with React, Node, and Typescript.

Comments:

Leave a comment: