WordPress Headless con NuxtJS y Netlify

WordPress Headless se basa en desacoplar la herramienta WordPress de la parte visual de la web. De esta manera WordPress se utiliza como administrador de contenidos y la parte frontal de la web se gestiona mediante alguna librería o framework javascript, como por ejemplo Vue.

NuxtJS es un framework de código abierto basado en Vue. Una de las grandes ventajas de NuxtJS es que es modular, por lo que permite que tu aplicación sea escalable de base, aparte de ser una tecnología actual que se centra en la experiencia del desarrollador.

Netlify es una plataforma que se utiliza para alojar nuestros sitios webs y que tiene muchas ventajas frente a los hostings habituales, ya que nos permite realizar de forma fácil e intuitiva integración continua, tener entornos de tests de nuestras webs, realizar la subida de ficheros mediante GIT, generar sitios estáticos, etc.

En este post veremos cómo realizar de forma «fácil» la implementación de WordPress Headless con NuxtJS (Vue) y Netlify. Además también daremos nuestra opinión sobre las ventajas y desventajas que implica todo esto.

Pre-requisitos

  1. Tener conocimientos de Vue y/o Javascript
  2. Haber utilizado alguna vez NPM y GIT

Crear un proyecto Vue con NuxtJS

En este apartado veremos cómo crear un proyecto desde cero en nuestro ordenador y ver de forma local el resultado. Para ello, deberemos seguir los siguientes pasos:

  1. Primero de todo necesitamos tener instalado Node y NPM en nuestro ordenador. En caso de no tenerlo, podéis seguir los pasos en la web oficial en este link.
  2. Crear un proyecto NuxtJS mediante NPM en la consola del ordenador. Para ello iremos a la carpeta que deseemos y ejecutaremos el siguiente comando:
npm init nuxt-app <project-name>

2. Posteriormente nos saldrán diversas preguntas para realizar la configuración de nuestro proyecto. Para este proyecto hemos aplicado lo siguiente:

Con esto ya tendríamos creado el proyecto y podremos ver el resultado ejecutando primero el siguiente comando en la raíz de nuestro proyecto y posteriormente accediendo a la ruta «http://localhost:3000/» en nuestro navegador:

npm run dev

El próximo paso es conectarse a la API de nuestro WordPress para obtener toda la información y mostrarla correctamente, cosa que veremos en el siguiente paso.

Conectarse a la API de WordPress

WordPress permite obtener toda la información de un sitio web mediante REST API. Esto quiere decir que mediante un comando GET podemos obtener los listados de los posts, el contenido de un posts, acceder a los Custom Post Types y mucha más información.

Para poder obtener la información de los post hemos de acceder a la siguiente url:

https://seocom.agency/wp-json/wp/v2/posts/

Si abrís la url anterior en una nueva pestaña de un navegador veréis que obtenemos la información de los posts del blog de Seocom, con toda la información de cada uno de ellos, como por ejemplo título, fecha de creación, contenido, tags, categorías, etc.

Para mostrar el listado de posts en la home de nuestra aplicación editaremos el fichero «index.vue» con el siguiente código:

<template>
  <div class="container">
    <div>
      <Logo />
      <h1 class="title">Seocom Headless WordPress</h1>
      <div class="posts" v-if="posts">
        <div class="post" v-for="post in posts" :key="post.id" >
          <nuxt-link :to="{name: 'post-id', params: { id:post.id } }">
            <h1 class="subtitle">
              {{post.title.rendered}}
            </h1>
            <p>{{post.excerpt.rendered | strippedContent}}</p>
            <p class="read-more">Leer más</p>
          </nuxt-link>
        </div>
      </div>
    </div>
  </div>
</template>
<script>
import axios from 'axios'
export default {
  data() {
    return {
      posts: {},
      error: []
    }
  },
  created() {
    this.fetchData()
  },
  watch: {
    '$route': 'fetchData'
  },
  methods: {
    fetchData() {
      return axios.get('https://seocom.agency/wp-json/wp/v2/posts/')
      .then(response => {
        this.posts = response.data;
        return;
      })
      .catch((error) => {
        return { error: error }
      })
    },
  },
  filters: {
    strippedContent: function(string) {
           return string.replace(/<\/?[^>]+>/ig, " "); 
    }
  },
}
</script>
<style>
.container {
  margin: 0 auto 20px;
  min-height: 100vh;
  text-align: center;
}
.title {
  font-family:'Quicksand','Source Sans Pro',-apple-system,BlinkMacSystemFont,'Segoe UI',Roboto,'Helvetica Neue',Arial,sans-serif;
  display: block;
  font-weight: 300;
  font-size: 100px;
  color: #35495e;
  letter-spacing: 1px;
}
.subtitle {
  font-weight: 300;
  font-size: 30px;
  line-height: 33px;
  color: #526488;
  word-spacing: 5px;
  padding-bottom: 15px;
}
.links {
  padding-top: 15px;
}
.posts {
  display: flex;
  justify-content: space-evenly;
  flex-wrap: wrap;
  margin-top: 20px;
}
.post {
  max-width: 350px;
  box-shadow: rgba(0, 0, 0, 0.16) 0px 1px 4px;
  padding: 10px;
  margin: 15px 10px;
}
a {
  text-decoration: none;
}
p {
  color: #444;
}
.read-more {
  background: #1e8775;
  color: white;
  font-weight: bold;
  margin-top: 10px;
  padding: 5px;
}
.post a {
  display: flex;
  flex-direction: column;
  justify-content: space-between;
  height: 100%;
}
</style>

Importante: deberemos instalar «axios» en nuestro proyecto. Este es un módulo que nos permite realizar peticiones GET. Para ello iremos a la raíz del proyecto en la consola de nuestro ordenador y ejecutaremos el siguiente comando:

npm install axios

Ahora crearemos una página para poder mostrar el contenido de cada post de forma individual. Para ello crearemos una carpeta llamada «/post» dentro de la carpeta «/pages» de nuestro proyecto, y en esta crearemos un fichero llamado «_id.vue».

En este caso la información del post la obtendremos del ID de dicho post, que viene dada en la url del navegador configurado en el paso anterior. El código necesario en este fichero es el siguiente:

<template>
  <section class="container">
    <div>
      <h1 class="title">
        {{post.title.rendered}}
      </h1>
      <span v-html="post.content.rendered"></span>
    </div>
  </section>
</template>
<script>
import axios from 'axios'
export default {
  head () {
    return {
      title: this.post._yoast_wpseo_title,
      meta: [
        { hid: 'description', id: 'description', name: 'description', content: this.post._yoast_wpseo_metadesc }
      ]
    }
  },
  asyncData ({ params }) {
    return axios.get(`http://seocom.agency/wp-json/wp/v2/posts/${params.id}`)
      .then(response => {
        console.log(response.data._yoast_wpseo_metadesc)
        return { post: response.data }
      })
      .catch((error) => {
        return { error: error }
      })
  },
  data () {
    return {
      post: {},
      error: []
    }
  }
}
</script>
<style>
.container {
  margin: 0 auto 20px;
  min-height: 100vh;
  padding: 20px;
}
.title {
  font-family: 'Quicksand', 'Source Sans Pro', -apple-system, BlinkMacSystemFont,
    'Segoe UI', Roboto, 'Helvetica Neue', Arial, sans-serif;
  display: block;
  font-weight: 300;
  font-size: 50px;
  color: #35495e;
  letter-spacing: 1px;
  margin-bottom: 20px;
}
h1, h2, h3, h4 {
    font-family: 'Quicksand', 'Source Sans Pro', -apple-system, BlinkMacSystemFont,
    'Segoe UI', Roboto, 'Helvetica Neue', Arial, sans-serif;
    color: #35495e;
    margin: 20px 0 10px;
}
a {
  color: #35495e;
}
p, ul, li {
  color: #444;
} 
img {
    margin: 10px auto;
    display: block;
}
</style>

Ahora mismo, si clicamos en uno de los posts de la home de nuestro proyecto local, veremos que nos lleva a una nueva página y esta se rellena con el contenido del post.

Una vez realizado esto, hay que subir el proyecto a la cuenta de GIT para posteriormente asignarlo a Netlify, cosa que veremos en el próximo apartado.

Subir nuestro proyecto a internet mediante Netlify

Creamos una cuenta en Netlify con GIT, para poder vincular el repositorio que hemos creado anteriormente con Netlify. En caso de no tener cuenta en GIT, también deberemos crearnos una cuenta, por ejemplo en GitHub.

Ahora desde Netlify, crearemos un nuevo sitio haciendo clic en «New site from Git».

En el siguiente paso vincularemos el usuario de GIT y seleccionaremos el repositorio deseado, que es el que hemos dado de alta anteriormente.

Finalmente hemos de definir los siguientes datos:

  • La rama a escoger será «master», que es la rama de producción.
  • El directorio base (Base directory) será la raíz del proyecto «/».
  • El comando que se utiliza para compilar es «npm run generate».
  • El campo «Publish directory» lo rellenaremos con «/dist», ya que es donde se generan los ficheros al compilar la aplicación.

Finalmente realizamos el deploy y nos crea un site dentro de Netlify. En la configuración se puede editar el nombre de la url para poner una url más amigable y que se adapte al nombre de nuestro proyecto. En nuestro caso hemos creado el siguiente: seocom-headless-wp.netlify.app.

¡Ya tenemos nuestro WordPress Headless accesible por todo el mundo!

Ventajas y desventajas de un WordPress Headless

Algunas de las ventajas son:

  • Permite centralizar el contenido en el backend de WordPress y que cualquier herramienta y/o desarrollo se nutra de él.
  • Puedes generar páginas estáticas de tus contenidos de manera que puedes crear webs más rápidas.
  • La escalabilidad es un aspecto a tener en cuenta para proyectos grandes, y utilizar la API de WordPress nos beneficia enormemente en este aspecto.
  • Todos sabemos que la seguridad en WordPress es uno de los grandes problemas. Con esta opción dejamos de lado las vulnerabilidades de WordPress de manera que hacemos más segura nuestra web.

Desventajas que conlleva este método de desarrollo:

  • Es necesario tener conocimientos de programación, de manera que puede que necesitemos un equipo técnico para desarrollarlo.
  • El mantenimiento es más complicado y complejo.
  • Perdemos la posibilidad de instalar muchos de los plugins de WordPress que tanto nos ayudan, por lo que habrá que desarrollar esas funcionalidades manualmente.
  • Perdemos el editor Gutenberg a la hora de crear contenido.

Extra SEO info

Como sabéis, somos una empresa de SEO, por lo que nos importa el SEO en todos nuestros proyectos. Para este caso hemos de comentar que la API de WordPress nos permite acceder también a la información de Yoast SEO, uno de los plugins más importantes relacionados con el SEO en WordPress.

En el proyecto anterior ya se tenía en cuenta esto, solo hay que tener en cuenta que hemos de hacer una pequeña modificación en el «functions.php» de nuestro WordPress:

<?phpadd_action( 'rest_api_init', 'slug_register_yoast_seo_meta' );function slug_register_yoast_seo_meta() {
    register_rest_field( 'post',
        '_yoast_wpseo_title',
        array(
            'get_callback'    => 'get_seo_meta_field',
            'update_callback' => null,
            'schema'          => null,
        )
    );
    register_rest_field( 'post',
        '_yoast_wpseo_metadesc',
        array(
            'get_callback'    => 'get_seo_meta_field',
            'update_callback' => null,
            'schema'          => null,
        )
    );
}function get_seo_meta_field( $object, $field_name, $request ) {
    return get_post_meta( $object[ 'id' ], $field_name, true );
}