<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Nimbel</title>
    <description>The latest articles on DEV Community by Nimbel (@nimbel).</description>
    <link>https://dev.to/nimbel</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Forganization%2Fprofile_image%2F3053%2F3fa40286-2ba9-465c-a3e7-3b87ace034b8.png</url>
      <title>DEV Community: Nimbel</title>
      <link>https://dev.to/nimbel</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/nimbel"/>
    <language>en</language>
    <item>
      <title>Como montar un blog estático con Next.js y dev.to como CMS</title>
      <dc:creator>dastasoft</dc:creator>
      <pubDate>Tue, 03 Nov 2020 14:30:11 +0000</pubDate>
      <link>https://dev.to/nimbel/como-montar-un-blog-estatico-con-next-js-y-dev-to-como-cms-4jmc</link>
      <guid>https://dev.to/nimbel/como-montar-un-blog-estatico-con-next-js-y-dev-to-como-cms-4jmc</guid>
      <description>&lt;p&gt;Vamos a montar un blog estático utilizando Next.js y dev.to como headless CMS.&lt;/p&gt;

&lt;p&gt;Si quieres ir directamente al resultado final &lt;a href="https://github.com/dastasoft/dev-cms-static-blog/settings" rel="noopener noreferrer"&gt;en este repo&lt;/a&gt; tienes el proyecto final que también sirve como boilerplate para futuros blogs estáticos.&lt;/p&gt;

&lt;h2&gt;
  
  
  Motivación
&lt;/h2&gt;

&lt;p&gt;Cuando estaba haciendo el blog para &lt;a href="//nimbel.net"&gt;Nimbel&lt;/a&gt; necesitaba hacer un blog de forma rápida y que se adaptase a la naturaleza estática del resto de la página. Desde Nimbel queriamos poder publicar articulos en &lt;a href="//dev.to"&gt;Dev.to&lt;/a&gt; y al mismo tiempo mantener actualizado el blog personal.&lt;/p&gt;

&lt;p&gt;La estrategia que seguiremos en este tutorial será:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Aprovechar las capacidades estáticas de NextJS y la API de Dev.to para hacer un fetch de los post del usuario en tiempo de build.&lt;/li&gt;
&lt;li&gt;Crear las rutas estáticas a todos los post que hemos hecho fetch.&lt;/li&gt;
&lt;li&gt;Utilizar los webhooks de Dev.to para que cada vez que el usuario cree y/o actualice un post, se genere un nuevo build de nuestro sitio estático.&lt;/li&gt;
&lt;li&gt;Crear una plantilla base (boileplate) que nos servirá para crear cualquier otro blog siguiendo esta misma estrategia.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Paso a paso
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Pre requisitos
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Cuenta de &lt;a href="//dev.to"&gt;dev.to&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Cuenta de &lt;a href="https://vercel.com/" rel="noopener noreferrer"&gt;Vercel&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://nodejs.org/" rel="noopener noreferrer"&gt;NodeJS&lt;/a&gt; 10.13+ instalado&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://nodejs.org/" rel="noopener noreferrer"&gt;npm&lt;/a&gt; o &lt;a href="https://classic.yarnpkg.com/" rel="noopener noreferrer"&gt;yarn&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Creación del proyecto
&lt;/h3&gt;

&lt;p&gt;En mi caso utilicé mi propio boilerplate de NextJS con TailwindCSS que podéis descargar desde &lt;a href="https://github.com/dastasoft/nextjs-boilerplate" rel="noopener noreferrer"&gt;aquí&lt;/a&gt; o simplemente utilizando uno de los siguientes comandos:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;yarn create next-app my-app-name &lt;span class="nt"&gt;--example&lt;/span&gt; &lt;span class="s2"&gt;"https://github.com/dastasoft/nextjs-boilerplate"&lt;/span&gt;

npx create-next-app my-app-name &lt;span class="nt"&gt;--use-npm&lt;/span&gt; &lt;span class="nt"&gt;--example&lt;/span&gt; &lt;span class="s2"&gt;"https://github.com/dastasoft/nextjs-boilerplate"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Esto os creará un nuevo proyecto NextJS con TailwindCSS ya configurado.&lt;/p&gt;

&lt;h3&gt;
  
  
  Estructura
&lt;/h3&gt;

&lt;p&gt;En NextJS no necesitamos definir rutas, cada JS que esté dentro de la carpeta &lt;code&gt;pages&lt;/code&gt; será considerado una ruta accesible (menos &lt;code&gt;_app&lt;/code&gt; y otros &lt;code&gt;_&lt;/code&gt; archivos que se consideran privados).&lt;/p&gt;

&lt;p&gt;Organizaremos el proyecto con las siguientes rutas:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;- pages
|- blog
|-- posts
|--- &lt;span class="o"&gt;[&lt;/span&gt;slug].js
|- _app.js
|- blog.js
|- index.js
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;_app.js&lt;/code&gt; contendrá el layout general de la aplicación que aplicaremos a todas las rutas de nuestra aplicación.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;blog.js&lt;/code&gt; contendrá la estructura general de la página dedicada al blog así como el fetch a los posts para poder mostrarlos en forma de tarjetas.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;index.js&lt;/code&gt; será nuestra pagina de inicio.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;blog/posts/[slug].js&lt;/code&gt; este punto necesita algo mas de explicación:

&lt;ul&gt;
&lt;li&gt;Al crear una estructura le estamos diciendo al router que en la ruta &lt;code&gt;nuestro-dominio/blog/posts/slug&lt;/code&gt; encontrará un elemento &lt;code&gt;slug&lt;/code&gt; que será dinámico y estará accesible mediante era ruta exacta.&lt;/li&gt;
&lt;li&gt;Dentro de ese JS deberemos definir que valor toma el parametro dinámico &lt;code&gt;slug&lt;/code&gt;, que en nuestro caso sera el propio slug (url) del post, por lo que deberemos hacer un fetch de ese post en concreto y consultar sus datos en tiempo de build.&lt;/li&gt;
&lt;li&gt;Deberemos definir todos los paths posibles (uno por cada post) de cara a que cuando el usuario navegue o escriba directamente en la url &lt;code&gt;nuestro-dominio/blog/post/este-post-existe&lt;/code&gt; ese slug ya este creado en tiempo de build, ya que la página es totalmente estática y no irá a consultar nuevos datos fuera del build*.&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;/ul&gt;

&lt;h3&gt;
  
  
  SSG vs SSR vs ISR
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;SSG (Static Site Generation), es el modo por defecto en el que trabaja NextJS, se puede utilizar en combinación con las funciones &lt;code&gt;getStaticProps&lt;/code&gt; y &lt;code&gt;getStaticPaths&lt;/code&gt; que provee el propio framework, las diferentes páginas se generan de forma estática en tiempo de build.&lt;/li&gt;
&lt;li&gt;SSR (Server Side Rendering), se generán las páginas bajo demanda por cada petición desde el servidor, se utiliza en combinación con la función &lt;code&gt;getServerSideProps&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;ISR (Incremental Static Regeneration), disponible a partir de la version 9.5 de NextJS. Te perimite actualizar páginas que se crearon como estáticas y al entrar una nueva petición se detecta que está en un estado obsoleto y debe re-renderizarse. Para activar ISR se añade una propiedad &lt;code&gt;revalidate&lt;/code&gt; en la función &lt;code&gt;gettaticProps&lt;/code&gt;.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;En esta guía vamos a tratar solo SSG, para información mas detallada de los otros metódos &lt;a href="https://nextjs.org/docs/basic-features/data-fetching" rel="noopener noreferrer"&gt;consultar la documentación oficial&lt;/a&gt;, NextJS no necesita ninguna configuración especial para cambiar (o incluso combinar!) entre los diferentes modos, todo recae en la utilización de las funciones especiales ligadas a cada tipo.&lt;/p&gt;

&lt;p&gt;Este es un apartado complejo y muy amplio y es precisamente donde NextJS brilla por la posibilidad de elegir fácilmente entre ellos o incluso combinarlos. Lo dejo para una futura guía :) la cual deberia explicar cuando utilizar unos metódos u otros segun la naturaleza de cada página.&lt;/p&gt;

&lt;p&gt;En nuestro caso, debido a que todos los datos los tenemos disponibles en tiempo de build, dado que los vamos a buscar a la API de dev.to y no tenemos que cambiar nada de nuestra web a menos que cambie algo en nuestro CMS (dev.to) no tiene sentido estar repitiendo las mismas consultas por cada usuario que entra.&lt;/p&gt;

&lt;h3&gt;
  
  
  Variables de entorno
&lt;/h3&gt;

&lt;p&gt;A lo largo de las siguientes secciones utilizaremos una variable de entorno para poder acceder al usuario de dev.to y poder descargarnos los articulos publicados. De cara al desarrollo en local utilizaremos el fichero &lt;code&gt;.env.development&lt;/code&gt; en el que añadiremos la siguiente variable de entorno:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;DEV_USERNAME&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;dastasoft
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Si utilizáis directamente el &lt;a href="https://github.com/dastasoft/dev-cms-static-blog" rel="noopener noreferrer"&gt;boilerplate&lt;/a&gt; solo tenéis que cambiar el valor de esta variable para que consulte vuestro usuario en vez del mio.&lt;/p&gt;

&lt;p&gt;Esta variable de entorno la necesitaremos configurar también en el momento del despliegue, en este tutorial desplegaremos la aplicación utilizando &lt;a href="https://vercel.com/" rel="noopener noreferrer"&gt;Vercel&lt;/a&gt; por lo que podéis consultar la seccion de &lt;code&gt;Despliegue&lt;/code&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  Creando el Blog
&lt;/h3&gt;

&lt;p&gt;Empezaremos creando el &lt;code&gt;blog.js&lt;/code&gt; en nuestra carpeta &lt;code&gt;pages&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;La parte mas importante es como hacemos fetch de todos los posts de un usuario en tiempo de build para poder pintar los posts como tarjetas, para ello utilizaremos una de las funciones SSG que nos proporciona NextJS, &lt;code&gt;getStaticProps&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;getStaticProps&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;async &lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;devDotToPosts&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nf"&gt;fetch&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="s2"&gt;`https://dev.to/api/articles?username=&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;process&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;env&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;DEV_USERNAME&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;`&lt;/span&gt;
  &lt;span class="p"&gt;);&lt;/span&gt;

  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;res&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;devDotToPosts&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;json&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="na"&gt;props&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="na"&gt;devDotToPosts&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;res&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="p"&gt;};&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Creando el Artículo
&lt;/h3&gt;

&lt;p&gt;El siguiente paso a realizar para que la generación estática sea posible es definir todas las posibles rutas que el usuario pueda visitar al entrar en esta página, para que sean accesibles las tenemos que pre-renderizar en tiempo de build y NextJS necesita saber la lista completa, esto lo conseguiremos con otra de las funciones que provee NextJS &lt;code&gt;getStaticPaths&lt;/code&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;getStaticPaths&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;devDotToPosts&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nf"&gt;fetch&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="s2"&gt;`https://dev.to/api/articles?username=&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;process&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;env&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;DEV_USERNAME&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;`&lt;/span&gt;
  &lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;posts&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;devDotToPosts&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;json&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="na"&gt;paths&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;posts&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;map&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;post&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="na"&gt;params&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
          &lt;span class="na"&gt;slug&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;post&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;slug&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;
      &lt;span class="p"&gt;};&lt;/span&gt;
    &lt;span class="p"&gt;}),&lt;/span&gt;
    &lt;span class="na"&gt;fallback&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;false&lt;/span&gt;
  &lt;span class="p"&gt;};&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Creamos una ruta por cada post publicado, utilizando su &lt;code&gt;slug&lt;/code&gt; como en el caso anterior. Definimos &lt;code&gt;fallback&lt;/code&gt; como &lt;code&gt;false&lt;/code&gt; ya que no planeamos soportar URLs que esten fuera de las que estamos generando estáticamente, tener esta propiedad a false devolverá un 404 si se intenta consultar cualquier URL que este fuera del array que proporcionamos en &lt;code&gt;paths&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Habilitar la propiedad &lt;code&gt;fallback&lt;/code&gt; tiene numerosas aplicaciones y puede ser utilizada en combinación con &lt;code&gt;Incremental Static Generation&lt;/code&gt; el cual es una opción muy potente dentro de NextJS, para más información sobre este tema &lt;a href="https://nextjs.org/docs/basic-features/data-fetching#getstaticpaths-static-generation" rel="noopener noreferrer"&gt;consultar la documentación oficial&lt;/a&gt;&lt;/p&gt;

&lt;h4&gt;
  
  
  Datos del artículo
&lt;/h4&gt;

&lt;p&gt;Dentro del artículo en concreto, necesitamos recuperar los datos, para ello consultaremos la API de dev.to usando el mismo &lt;code&gt;slug&lt;/code&gt; con el que hemos construido la URL.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;getStaticProps&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;async &lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="nx"&gt;params&lt;/span&gt; &lt;span class="p"&gt;})&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;devDotToPost&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nf"&gt;fetch&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="s2"&gt;`https://dev.to/api/articles/&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;process&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;env&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;DEV_USERNAME&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;/&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;params&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;slug&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;`&lt;/span&gt;
  &lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;res&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;devDotToPost&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;json&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="na"&gt;props&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="na"&gt;devDotToPost&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;res&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="p"&gt;};&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Todos los datos que nos llegan desde la API de dev.to los pasamos en tiempo de build a la página del artículo en concreto, estos datos serán accesibles a través de la &lt;code&gt;prop&lt;/code&gt; &lt;code&gt;devDotToPost&lt;/code&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="k"&gt;default&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;Post&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="nx"&gt;devDotToPost&lt;/span&gt; &lt;span class="p"&gt;})&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="p"&gt;...&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h4&gt;
  
  
  Imprimir el markdown
&lt;/h4&gt;

&lt;p&gt;Una vez ya tenemos los datos del artículo, entre los múltiples campos que nos llegan de la API, el contenido en markdown está en &lt;code&gt;body_html&lt;/code&gt;, para utilizarlo:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;div&lt;/span&gt; &lt;span class="nx"&gt;className&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;markdown&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="nx"&gt;dangerouslySetInnerHTML&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{{&lt;/span&gt; &lt;span class="na"&gt;__html&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;body_html&lt;/span&gt; &lt;span class="p"&gt;}}&lt;/span&gt; &lt;span class="sr"&gt;/&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;En la clase &lt;code&gt;markdown&lt;/code&gt; deberás definir como quieres que se vean los elementos contenidos en el markdown ya que la API devuelve una versión raw del markdown. En el &lt;a href="https://github.com/dastasoft/dev-cms-static-blog/blob/master/styles/index.css" rel="noopener noreferrer"&gt;proyecto de ejemplo&lt;/a&gt; tienes disponible una propuesta simple.&lt;/p&gt;

&lt;h4&gt;
  
  
  [slug].js al completo
&lt;/h4&gt;

&lt;p&gt;Así es como queda nuestra template para cualquier artículo, podéis verlo directamente en el &lt;a href="https://github.com/dastasoft/dev-cms-static-blog/blob/master/pages/blog/posts/%5Bslug%5D.js" rel="noopener noreferrer"&gt;repo&lt;/a&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;Head&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;next/head&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;Link&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;next/link&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;TopButton&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;../../../components/TopButton&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="k"&gt;default&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;Post&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="nx"&gt;devDotToPost&lt;/span&gt; &lt;span class="p"&gt;})&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;title&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="nx"&gt;published_at&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="nx"&gt;social_image&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="nx"&gt;body_html&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="nx"&gt;user&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="nx"&gt;type_of&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="nx"&gt;description&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="nx"&gt;canonical_url&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;devDotToPost&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;date&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Date&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;published_at&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;formatedDate&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;`&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;date&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;getDate&lt;/span&gt;&lt;span class="p"&gt;()}&lt;/span&gt;&lt;span class="s2"&gt;/&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;
    &lt;span class="nf"&gt;parseInt&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;date&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;getMonth&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt; &lt;span class="mi"&gt;10&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;/&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;date&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;getFullYear&lt;/span&gt;&lt;span class="p"&gt;()}&lt;/span&gt;&lt;span class="s2"&gt;`&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

  &lt;span class="k"&gt;return &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;div&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
      &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;Head&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
        &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;meta&lt;/span&gt; &lt;span class="nx"&gt;property&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;og:type&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="nx"&gt;content&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;type_of&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="sr"&gt;/&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;        &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;meta&lt;/span&gt; &lt;span class="nx"&gt;property&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;og:title&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="nx"&gt;content&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;title&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="sr"&gt;/&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;        &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;meta&lt;/span&gt; &lt;span class="nx"&gt;property&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;og:description&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="nx"&gt;content&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;description&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="sr"&gt;/&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;        &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;meta&lt;/span&gt; &lt;span class="nx"&gt;property&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;og:image&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="nx"&gt;content&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;social_image&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="sr"&gt;/&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;        &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;meta&lt;/span&gt; &lt;span class="nx"&gt;property&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;og:url&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="nx"&gt;content&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;canonical_url&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="sr"&gt;/&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;      &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/Head&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;      &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;div&lt;/span&gt; &lt;span class="nx"&gt;className&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;flex justify-center&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
        &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;TopButton&lt;/span&gt; &lt;span class="o"&gt;/&amp;gt;&lt;/span&gt;
        &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;article&lt;/span&gt; &lt;span class="nx"&gt;className&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;text-xs w-full md:w-3/4 &lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
          &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;div&lt;/span&gt; &lt;span class="nx"&gt;className&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;border-2 text-black bg-white md:rounded-lg overflow-hidden&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
            &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;img&lt;/span&gt; &lt;span class="nx"&gt;className&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;w-full&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="nx"&gt;src&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;social_image&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="nx"&gt;alt&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;title&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="sr"&gt;/&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;            &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;div&lt;/span&gt; &lt;span class="nx"&gt;className&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;p-4 md:p-32&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
              &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;h1&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;title&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/h1&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;              &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;div&lt;/span&gt; &lt;span class="nx"&gt;className&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;flex items-center text-gray-600&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
                &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;img&lt;/span&gt;
                  &lt;span class="nx"&gt;className&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;rounded-full w-12&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;
                  &lt;span class="nx"&gt;src&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;user&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;profile_image_90&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
                  &lt;span class="nx"&gt;alt&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;user&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;name&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
                &lt;span class="sr"&gt;/&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;                &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;span&lt;/span&gt; &lt;span class="nx"&gt;className&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;mx-4&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;user&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;name&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/span&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;                &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;span&lt;/span&gt; &lt;span class="nx"&gt;className&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;text-sm&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;formatedDate&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/span&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;              &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/div&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;              &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;div&lt;/span&gt;
                &lt;span class="nx"&gt;className&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;markdown&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;
                &lt;span class="nx"&gt;dangerouslySetInnerHTML&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{{&lt;/span&gt; &lt;span class="na"&gt;__html&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;body_html&lt;/span&gt; &lt;span class="p"&gt;}}&lt;/span&gt;
              &lt;span class="sr"&gt;/&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;            &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/div&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;          &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/div&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;          &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;Link&lt;/span&gt; &lt;span class="nx"&gt;href&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;/blog&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
            &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;a&lt;/span&gt; &lt;span class="nx"&gt;className&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;text-blue-500 inline-flex items-center md:mb-2 lg:mb-0 cursor-pointer text-base pb-8&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
              &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;svg&lt;/span&gt;
                &lt;span class="nx"&gt;className&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;w-4 h-4 mr-2&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;
                &lt;span class="nx"&gt;stroke&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;currentColor&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;
                &lt;span class="nx"&gt;strokeWidth&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;2&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;
                &lt;span class="nx"&gt;fill&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;none&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;
                &lt;span class="nx"&gt;strokeLinecap&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;round&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;
                &lt;span class="nx"&gt;strokeLinejoin&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;round&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;
                &lt;span class="nx"&gt;viewBox&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;0 0 24 24&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;
              &lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
                &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;path&lt;/span&gt; &lt;span class="nx"&gt;d&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;M19 12H5M12 19l-7-7 7-7&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="o"&gt;/&amp;gt;&lt;/span&gt;
              &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/svg&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;              &lt;span class="nx"&gt;Back&lt;/span&gt;
            &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/a&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;          &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/Link&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;        &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/article&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;      &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/div&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;    &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/div&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;  &lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;getStaticProps&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;async &lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="nx"&gt;params&lt;/span&gt; &lt;span class="p"&gt;})&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;devDotToPost&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nf"&gt;fetch&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="s2"&gt;`https://dev.to/api/articles/&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;process&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;env&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;DEV_USERNAME&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;/&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;params&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;slug&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;`&lt;/span&gt;
  &lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;res&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;devDotToPost&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;json&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="na"&gt;props&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="na"&gt;devDotToPost&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;res&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="p"&gt;};&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;getStaticPaths&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;devDotToPosts&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nf"&gt;fetch&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="s2"&gt;`https://dev.to/api/articles?username=&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;process&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;env&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;DEV_USERNAME&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;`&lt;/span&gt;
  &lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;posts&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;devDotToPosts&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;json&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="na"&gt;paths&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;posts&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;map&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;post&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="na"&gt;params&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
          &lt;span class="na"&gt;slug&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;post&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;slug&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;
      &lt;span class="p"&gt;};&lt;/span&gt;
    &lt;span class="p"&gt;}),&lt;/span&gt;
    &lt;span class="na"&gt;fallback&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;false&lt;/span&gt;
  &lt;span class="p"&gt;};&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Layout
&lt;/h3&gt;

&lt;p&gt;Para crear el layout y que aplique a todas las pantallas, lo crearemos en el fichero &lt;code&gt;_app.js&lt;/code&gt; e internamente NextJS lo añadirá a todas las paginas:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;Link&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;next/link&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;../styles/index.css&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="k"&gt;default&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;App&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="nx"&gt;Component&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;pageProps&lt;/span&gt; &lt;span class="p"&gt;})&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;return &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;div&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
      &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;nav&lt;/span&gt; &lt;span class="nx"&gt;className&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;p-4 flex justify-center items-center mb-4&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="nx"&gt;id&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;nav&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
        &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;Link&lt;/span&gt; &lt;span class="nx"&gt;href&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;/&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
          &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;span&lt;/span&gt; &lt;span class="nx"&gt;className&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;text-xl font-bold cursor-pointer mr-4&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="nx"&gt;Home&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/span&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;        &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/Link&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;        &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;Link&lt;/span&gt; &lt;span class="nx"&gt;href&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;/blog&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
          &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;span&lt;/span&gt; &lt;span class="nx"&gt;className&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;text-xl font-bold cursor-pointer&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="nx"&gt;Blog&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/span&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;        &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/Link&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;      &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/nav&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;      &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;main&lt;/span&gt; &lt;span class="nx"&gt;className&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;container px-5 mx-auto&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
        &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;Component&lt;/span&gt; &lt;span class="p"&gt;{...&lt;/span&gt;&lt;span class="nx"&gt;pageProps&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="sr"&gt;/&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;      &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/main&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;    &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/div&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;  &lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Lo importante en este punto es:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Utilizar el componente &lt;code&gt;Link&lt;/code&gt; de NextJS para que la navegación sea correcta&lt;/li&gt;
&lt;li&gt;Es el sitio ideal para importar el archivo de css y que aplique de forma global.&lt;/li&gt;
&lt;li&gt;Asegurarse de tener &lt;code&gt;&amp;lt;Component {...pageProps} /&amp;gt;&lt;/code&gt; ya que sin esto no veremos los componentes hijos, (similar a la utilizacion de &lt;code&gt;children&lt;/code&gt; en React)&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Home
&lt;/h3&gt;

&lt;p&gt;Definir la pagina principal en NextJS es tan sencillo como crear el fichero &lt;code&gt;index.js&lt;/code&gt; dentro de la carpeta &lt;code&gt;pages&lt;/code&gt; y NextJS creará automáticamente una ruta, en este caso a &lt;code&gt;/&lt;/code&gt;, la cual mezclará lo que hayamos definido en el fichero &lt;code&gt;_app.js&lt;/code&gt; mas el propio &lt;code&gt;index.js&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Esta es la propuesta de home page para el proyecto:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;DevDotToLogo&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;../public/devdotto.svg&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;NextLogo&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;../public/nextjs.svg&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="k"&gt;default&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;Home&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;return &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;div&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
      &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;div&lt;/span&gt; &lt;span class="nx"&gt;className&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;flex justify-center items-center&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
        &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;a&lt;/span&gt;
          &lt;span class="nx"&gt;href&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;https://nextjs.org/&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;
          &lt;span class="nx"&gt;target&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;_blank&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;
          &lt;span class="nx"&gt;rel&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;noopener noreferrer&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;
          &lt;span class="nx"&gt;aria&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="nx"&gt;label&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;NextJS&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;
        &lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
          &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;NextLogo&lt;/span&gt; &lt;span class="nx"&gt;className&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;mr-4&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="nx"&gt;width&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;100px&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="nx"&gt;height&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;100px&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="o"&gt;/&amp;gt;&lt;/span&gt;
        &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/a&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;        &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;span&lt;/span&gt; &lt;span class="nx"&gt;className&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;text-2xl&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="nx"&gt;Blog&lt;/span&gt; &lt;span class="nx"&gt;Boilerplate&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/span&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;      &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/div&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;
      &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;div&lt;/span&gt; &lt;span class="nx"&gt;className&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;flex justify-center items-center&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
        &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;span&lt;/span&gt; &lt;span class="nx"&gt;className&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;text-2xl&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="kd"&gt;with&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/span&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;        &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;a&lt;/span&gt;
          &lt;span class="nx"&gt;href&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;https://dev.to/&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;
          &lt;span class="nx"&gt;target&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;_blank&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;
          &lt;span class="nx"&gt;rel&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;noopener noreferrer&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;
          &lt;span class="nx"&gt;aria&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="nx"&gt;label&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Dev.to&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;
        &lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
          &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;DevDotToLogo&lt;/span&gt; &lt;span class="nx"&gt;className&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;mx-4&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="nx"&gt;width&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;100px&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="nx"&gt;height&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;100px&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="o"&gt;/&amp;gt;&lt;/span&gt;
        &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/a&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;        &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;span&lt;/span&gt; &lt;span class="nx"&gt;className&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;text-2xl&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="nx"&gt;a&lt;/span&gt; &lt;span class="nx"&gt;CMS&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/span&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;      &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/div&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;    &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/div&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;  &lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;En este caso se utilizan &lt;code&gt;anchor&lt;/code&gt; normales ya que son enlaces al exterior y NextJS no tiene que acceder a ningua ruta interna.&lt;/p&gt;

&lt;h3&gt;
  
  
  CSS
&lt;/h3&gt;

&lt;p&gt;NextJS mostrará errores si intentáis introducir CSS que puedan afectar de forma global fuera del archivo &lt;code&gt;_app.js&lt;/code&gt;, por ello en los demas sitios como páginas y/o componentes es recomendable utilizar soluciones como &lt;code&gt;emotionjs&lt;/code&gt;, &lt;code&gt;styled-components&lt;/code&gt;, &lt;code&gt;css-modules&lt;/code&gt; o &lt;code&gt;tailwindcss&lt;/code&gt; como en esta guía, que tienen su rango de efecto limitado al propio componente.&lt;/p&gt;

&lt;p&gt;NextJS provee su propia solución &lt;code&gt;CSS-in-JS&lt;/code&gt; llamada &lt;code&gt;styled-jsx&lt;/code&gt; pero últimamente de los propios proyectos quick-start de NextJS se ha optado por implementar &lt;code&gt;css-modules&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Si quereis conocer mejor que opciones tenéis para temas de estilo podéis consultar &lt;a href="https://dev.to/dastasoft/styling-in-react-4fbj"&gt;mi guia de estilos en React&lt;/a&gt; la cual aplica en su mayoria para NextJS, la diferencia principal es que no podemos aplicar estilos globales como hemos comentado anteriormente.&lt;/p&gt;

&lt;h1&gt;
  
  
  Despliegue
&lt;/h1&gt;

&lt;p&gt;Desplegaremos este proyecto en la plataforma de los mismos creadores de NextJS que es &lt;a href="https://vercel.com/" rel="noopener noreferrer"&gt;Vercel&lt;/a&gt;. Para desplegar un proyecto en Vercel debéis seguir los siguientes pasos:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Crear una cuenta en Vercel&lt;/li&gt;
&lt;li&gt;Pulsar en &lt;code&gt;Import Project&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Importaremos el proyecto directamente de nuestro repositorio Git&lt;/li&gt;
&lt;li&gt;Proporcionar la URL del repositorio GIT.&lt;/li&gt;
&lt;li&gt;En caso de que el paso anterior os de el error: &lt;code&gt;Couldn’t find the Git repository. If it exists, verify that the GitHub Integration is permitted to access it in the GitHub App Settings.&lt;/code&gt; pulsar en &lt;code&gt;GitHub App Settings&lt;/code&gt; y añadir el repositorio que intentáis desplegar a la lista de accesos de Vercel, si es el primer despliegue que realizais os pedirá acceso como parte del proceso.&lt;/li&gt;
&lt;li&gt;Una vez Vercel tenga visibilidad sobre el repositorio Git podremos darle un nombre, que puede ser cualquiera no tiene porque coincidir con git, un &lt;code&gt;Framework preset&lt;/code&gt; que dejaremos tal y como esta marcado en Next.js, &lt;code&gt;Build and Output Settings&lt;/code&gt; que por el momento no necesitaremos cambiar nada y por último &lt;code&gt;Environment Variables&lt;/code&gt; aqui tendremos que crear la variable de entorno que definimos anteriormente en &lt;code&gt;.env.development&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Dentro de &lt;code&gt;Environment Variables&lt;/code&gt; definimos la variable &lt;code&gt;DEV_USERNAME&lt;/code&gt; con el valor del usuario sobre el que queráis hacer las consultas, en mi caso &lt;code&gt;dastasoft&lt;/code&gt; y pulsamos &lt;code&gt;Add&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Pulsamos &lt;code&gt;Deploy&lt;/code&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Es posible que la primera vez el despliegue falle dando errores de recibir respuestas JSON erroneas, en mi caso intentando el despliegue una segunda vez me funcionó sin problemas.&lt;/p&gt;

&lt;p&gt;Podéis ver el resultado final desplegando el boilerplate que hemos construido en este tutorial en [&lt;a href="https://dev-cms-static-blog.vercel.app/(https://dev-cms-static-blog.vercel.app/)" rel="noopener noreferrer"&gt;https://dev-cms-static-blog.vercel.app/(https://dev-cms-static-blog.vercel.app/)&lt;/a&gt;&lt;/p&gt;

&lt;h1&gt;
  
  
  Actualización automática
&lt;/h1&gt;

&lt;p&gt;Ya casi estamos, pero nos falta el paso más importante, ahora mismo tenemos un blog que se genera en tiempo de build de forma estática, eso quiere decir que cuando el proyecto se despliega en Vercel, se lanzan todas las consultas necesarias a dev.to para obtener la información necesaria y con eso se construye una web totalmente estática en la que por muchas visitas que tengamos, no se vuelve a consultar a dev.to para recuperar artículos.&lt;/p&gt;

&lt;p&gt;Pero y si publicamos/editamos un artículo? Necesitamos una forma de decirle a Vercel que debe volver a pasar esa fase de build y recuperar la información más actualizada, para ello utilizaremos webhooks.&lt;/p&gt;

&lt;h2&gt;
  
  
  Crear una URL de acceso al despliegue
&lt;/h2&gt;

&lt;p&gt;Dentro del proyecto en Vercel, debemos ir a &lt;code&gt;Settings&lt;/code&gt; a la sección referente a &lt;code&gt;Git&lt;/code&gt; y buscar el cuadro &lt;code&gt;Deploy Hooks&lt;/code&gt;, aquí crearemos un nuevo hook al cual le podemos dar el nombre que queramos y que este en nuestra rama principal de git, en mi caso:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Nombre: dev.to&lt;/li&gt;
&lt;li&gt;Git Branch Name: master&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Esto nos generará una URL del tipo &lt;code&gt;https://api.vercel.com/v1/integrations/deploy/xxxxxxxxxxxxxxxxxxx&lt;/code&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Crear webhooks en dev.to
&lt;/h2&gt;

&lt;p&gt;En el &lt;code&gt;README.md&lt;/code&gt; del &lt;a href="https://github.com/dastasoft/dev-cms-static-blog/blob/master/README.md" rel="noopener noreferrer"&gt;boilerplate&lt;/a&gt; teneis los comandos disponibles para consultar, crear y eliminar webhooks en vuestra cuenta de dev.to.&lt;/p&gt;

&lt;p&gt;Necesitaréis acceso a una Terminal y el paquete curl, además en vuestra cuenta de dev.to necesitaréis crear una &lt;code&gt;DEV API Key&lt;/code&gt;, esto lo podéis hacer accediendo a dev.to con vuestra cuenta en el apartado &lt;code&gt;Settings&lt;/code&gt;, &lt;code&gt;Account&lt;/code&gt; y en la sección &lt;code&gt;DEV API Keys&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Para crear la DEV API Key hay que proporcionar un nombre y pulsar en &lt;code&gt;Generate API Key&lt;/code&gt;, esto nos generará un hash que necesitaremos en los siguientes comandos.&lt;/p&gt;

&lt;p&gt;Con una terminal abierta utilizamos el siguiente comando para crear el webhook en nuestra cuenta de dev.to&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;curl &lt;span class="nt"&gt;-X&lt;/span&gt; POST &lt;span class="nt"&gt;-H&lt;/span&gt; &lt;span class="s2"&gt;"Content-Type: application/json"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-H&lt;/span&gt; &lt;span class="s2"&gt;"api-key: API_KEY"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-d&lt;/span&gt; &lt;span class="s1"&gt;'{"webhook_endpoint":{"target_url":"TARGET_URL","source":"DEV","events":["article_created", "article_updated"]}}'&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  https://dev.to/api/webhooks
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Donde &lt;code&gt;API_KEY&lt;/code&gt; es la DEV API Key que hemos creado en dev.to y &lt;code&gt;TARGET_URL&lt;/code&gt; (importante mantener las ") es la URL de acceso al despliegue que hemos creado en &lt;code&gt;Deploy Hooks&lt;/code&gt; de Vercel. En este ejemplo estamos poniendo a la escucha el webhook para los eventos de creación de artículos y también para la edición, podéis dejar los eventos que os interesen.&lt;/p&gt;

&lt;h2&gt;
  
  
  Comprobar webhook
&lt;/h2&gt;

&lt;p&gt;En una terminal con curl disponible ejecutar el siguiente comando:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;curl &lt;span class="nt"&gt;-H&lt;/span&gt; &lt;span class="s2"&gt;"api-key: API_KEY"&lt;/span&gt; https://dev.to/api/webhooks
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Donde &lt;code&gt;API_KEY&lt;/code&gt; es la DEV API Key que hemos creado en dev.to.&lt;/p&gt;

&lt;p&gt;Debe respondernos con un array el cual no debe estar vacío ya que en el paso anterior creamos un webhook. Si os sale como respuesta un array vacío, comprobad el paso anterior.&lt;/p&gt;

&lt;h1&gt;
  
  
  Conclusión
&lt;/h1&gt;

&lt;p&gt;Si se ha creado satisfactoriamente el webhook, lo que habremos conseguido es que cada vez que un artículo se cree o se edite (segun los eventos que hayais utilizado) llamará a la URL que le hemos porporcionado, esta URL desencadenará un nuevo build en Vercel que volverá a consultar la API de dev.to y encontrará el nuevo artículo generando de nuevo una versión totalmente estática de nuestro blog.&lt;/p&gt;

&lt;p&gt;Con esto ya tendríamos completados los requisitos que nos habiamos fijado al principio de este tutorial! Os animo a indagar más en el proyecto &lt;a href="https://github.com/dastasoft/dev-cms-static-blog" rel="noopener noreferrer"&gt;boilerplate&lt;/a&gt; sobre el que esta basado este tutorial para que lo podáis utilizar como base para futuros proyectos.&lt;/p&gt;

&lt;p&gt;Ahora es vuestro turno, cual es vuestra experiencia creando blogs? Crees que es más sencillo de la forma que lo haces actualmente o con esta forma? Ya utilizabas esta forma o una parecida, cuentame tu caso de éxito o tus preguntas :D&lt;/p&gt;

&lt;p&gt;Con un poco de suerte, este post creará una nueva entrada en el &lt;a href="https://nimbel.net/blog" rel="noopener noreferrer"&gt;Blog de Nimbel&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Disfrutad!&lt;/p&gt;

</description>
      <category>nextjs</category>
      <category>react</category>
      <category>javascript</category>
      <category>spanish</category>
    </item>
    <item>
      <title>Simple Static Blog with Next.js and dev.to as CMS</title>
      <dc:creator>dastasoft</dc:creator>
      <pubDate>Mon, 26 Oct 2020 23:37:17 +0000</pubDate>
      <link>https://dev.to/nimbel/simple-static-blog-with-next-js-and-dev-to-as-cms-4pej</link>
      <guid>https://dev.to/nimbel/simple-static-blog-with-next-js-and-dev-to-as-cms-4pej</guid>
      <description>&lt;p&gt;UPDATE: Added Next v10 with new Image component&lt;/p&gt;

&lt;p&gt;We are going to set up a static blog using Next.js and dev.to as a headless CMS.&lt;/p&gt;

&lt;p&gt;If you want to go directly to the final result &lt;a href="https://github.com/dastasoft/dev-cms-static-blog" rel="noopener noreferrer"&gt;in this repo&lt;/a&gt; you have the final project that also serves as a boilerplate for future static blogs.&lt;/p&gt;

&lt;h2&gt;
  
  
  Motivation
&lt;/h2&gt;

&lt;p&gt;When I was blogging for &lt;a href="//nimbel.net"&gt;Nimbel&lt;/a&gt; I needed to make a blog quickly that would fit the static nature of the rest of the page. Nimbel wanted to be able to publish articles in &lt;a href="//dev.to"&gt;Dev.to&lt;/a&gt; and at the same time keep the personal blog updated.&lt;/p&gt;

&lt;p&gt;The strategy we will follow in this tutorial will be:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Take advantage of the static capabilities of NextJS and the Dev.to API to fetch the user's posts at build time.&lt;/li&gt;
&lt;li&gt;Create the static paths to all the posts we have fetched.&lt;/li&gt;
&lt;li&gt;Use Dev.to's webhooks so that every time the user creates and/or updates a post, a new build of our static site is generated.&lt;/li&gt;
&lt;li&gt;Create a base template (boileplate) that will be used to create any other blog following this same strategy.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Step by step
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Pre-requisites
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;a href="//dev.to"&gt;dev.to&lt;/a&gt; account&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://vercel.com/" rel="noopener noreferrer"&gt;Vercel&lt;/a&gt; account&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://nodejs.org/" rel="noopener noreferrer"&gt;NodeJS&lt;/a&gt; 10.13+ installed&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://nodejs.org/" rel="noopener noreferrer"&gt;npm&lt;/a&gt; or &lt;a href="https://classic.yarnpkg.com/" rel="noopener noreferrer"&gt;yarn&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Creation of the project
&lt;/h3&gt;

&lt;p&gt;In my case I used my own NextJS boilerplate with TailwindCSS that you can download from &lt;a href="https://github.com/dastasoft/nextjs-boilerplate" rel="noopener noreferrer"&gt;here&lt;/a&gt; or simply using one of the following commands:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;yarn create next-app my-app-name &lt;span class="nt"&gt;--example&lt;/span&gt; &lt;span class="s2"&gt;"https://github.com/dastasoft/nextjs-boilerplate"&lt;/span&gt;

npx create-next-app my-app-name &lt;span class="nt"&gt;--use-npm&lt;/span&gt; &lt;span class="nt"&gt;--example&lt;/span&gt; &lt;span class="s2"&gt;"https://github.com/dastasoft/nextjs-boilerplate"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This will create a new NextJS project with TailwindCSS already configured.&lt;/p&gt;

&lt;h3&gt;
  
  
  Structure
&lt;/h3&gt;

&lt;p&gt;In NextJS we don't need to define paths, each JS that is inside the &lt;code&gt;pages&lt;/code&gt; folder will be considered an accessible path (minus &lt;code&gt;_app&lt;/code&gt; and other &lt;code&gt;_&lt;/code&gt; files that are considered private).&lt;/p&gt;

&lt;p&gt;We will organize the project with the following paths:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;- pages
|- blog
|-- posts
|--- &lt;span class="o"&gt;[&lt;/span&gt;slug].js
|- _app.js
|- blog.js
|- index.js
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;_app.js&lt;/code&gt; will contain the general layout of the application that we will apply to all the paths of our application.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;blog.js&lt;/code&gt; will contain the general structure of the blog page as well as the fetch for the posts to be able to display them in the form of cards.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;index.js&lt;/code&gt; will be our home page.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;blog/posts/[slug].js&lt;/code&gt; this point needs some additional explanation:

&lt;ul&gt;
&lt;li&gt;By creating a structure we're telling the router that in the path &lt;code&gt;our-domain/blog/posts/slug&lt;/code&gt; it will find a &lt;code&gt;slug&lt;/code&gt; element that will be dynamic and accessible via the exact path.&lt;/li&gt;
&lt;li&gt;Within this JS we must define what value the dynamic parameter &lt;code&gt;slug&lt;/code&gt; takes, which in our case will be the slug (url) of the post itself, so we must fetch that particular post and check its data at build time.&lt;/li&gt;
&lt;li&gt;We must define all the possible paths (one for each post) so that when the user navigates or writes directly in the url &lt;code&gt;our-domain/blog/post/this-post&lt;/code&gt; that slug is already created at build time, since the page is completely static and will not go to consult new data outside the build.&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;/ul&gt;

&lt;h3&gt;
  
  
  SSG vs SSR vs ISR
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;SSG (Static Site Generation), is the default mode in which NextJS works, it can be used in combination with the &lt;code&gt;getStaticProps&lt;/code&gt; and &lt;code&gt;getStaticPaths&lt;/code&gt; functions provided by the framework, the different pages are generated statically at build time.&lt;/li&gt;
&lt;li&gt;SSR (Server Side Rendering), pages are generated on demand for each request from the server, is used in combination with the &lt;code&gt;getServerSideProps&lt;/code&gt; function.&lt;/li&gt;
&lt;li&gt;ISR (Incremental Static Regeneration), available from version 9.5 of NextJS. It allows you to update pages that were created as static and when a new request is entered it is detected to be in an obsolete state and must be re-rendered. To activate ISR a 're-validate' property is added to the 'object' function.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;In this guide we are going to treat only SSG, for more detailed information of the other methods &lt;a href="https://nextjs.org/docs/basic-features/data-fetching" rel="noopener noreferrer"&gt;see the official documentation&lt;/a&gt;, NextJS does not need any special configuration to change (or even combine!) between the different modes, it all lies in the use of the special functions linked to each type.&lt;/p&gt;

&lt;p&gt;This is a complex and very extensive section and it is precisely where NextJS shines by the possibility of easily choosing between them or even combining them. I leave it for a future guide :) which should explain when to use some methods or others according to the nature of each page.&lt;/p&gt;

&lt;p&gt;In our case, because we have all the data available at build time, since we are going to look for it in the dev.to API and we don't have to change anything on our website unless something changes in our CMS (dev.to) it doesn't make sense to be repeating the same queries for each user that enters.&lt;/p&gt;

&lt;h3&gt;
  
  
  Environment Variables
&lt;/h3&gt;

&lt;p&gt;Throughout the following sections we will use an environment variable to access the dev.to user and download the published articles. For local development we will use the &lt;code&gt;.env.development&lt;/code&gt; file in which we will add the following environment variable:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;DEV_USERNAME&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;dastasoft
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If you use the &lt;a href="https://github.com/dastasoft/dev-cms-static-blog" rel="noopener noreferrer"&gt;boilerplate&lt;/a&gt; directly, you only have to change the value of this variable.&lt;/p&gt;

&lt;p&gt;This environment variable will also need to be configured at the time of deployment, in this tutorial we will deploy the application using &lt;a href="https://vercel.com/" rel="noopener noreferrer"&gt;Vercel&lt;/a&gt; so you can check the section of &lt;code&gt;Deployment&lt;/code&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  Creating the Blog
&lt;/h3&gt;

&lt;p&gt;We will start by creating the &lt;code&gt;blog.js&lt;/code&gt; in our &lt;code&gt;pages&lt;/code&gt; folder.&lt;/p&gt;

&lt;p&gt;The most important part is how we fetch all the posts of a user at build time to be able to display the posts as cards, for this we will use one of the SSG functions provided by NextJS, &lt;code&gt;getStaticProps&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;getStaticProps&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;async &lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;devDotToPosts&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nf"&gt;fetch&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="s2"&gt;`https://dev.to/api/articles?username=&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;process&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;env&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;DEV_USERNAME&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;`&lt;/span&gt;
  &lt;span class="p"&gt;);&lt;/span&gt;

  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;res&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;devDotToPosts&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;json&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="na"&gt;props&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="na"&gt;devDotToPosts&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;res&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="p"&gt;},&lt;/span&gt;
  &lt;span class="p"&gt;};&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Creating the Article
&lt;/h3&gt;

&lt;p&gt;The next step to make the static generation possible is to define all the possible paths that the user can visit when entering this page, to be accessible we have to pre-render them at build time and NextJS needs to know the complete list, this will be achieved with another of the functions provided by NextJS &lt;code&gt;getStaticPaths&lt;/code&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;getStaticPaths&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;devDotToPosts&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nf"&gt;fetch&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="s2"&gt;`https://dev.to/api/articles?username=&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;process&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;env&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;DEV_USERNAME&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;`&lt;/span&gt;
  &lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;posts&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;devDotToPosts&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;json&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="na"&gt;paths&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;posts&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;map&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;post&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="na"&gt;params&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
          &lt;span class="na"&gt;slug&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;post&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;slug&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="p"&gt;},&lt;/span&gt;
      &lt;span class="p"&gt;};&lt;/span&gt;
    &lt;span class="p"&gt;}),&lt;/span&gt;
    &lt;span class="na"&gt;fallback&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="p"&gt;};&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We create a route for each published post, using its &lt;code&gt;slug&lt;/code&gt; as in the previous case. We define &lt;code&gt;fallback&lt;/code&gt; as &lt;code&gt;false&lt;/code&gt; since we do not plan to support URLs that are outside of the ones we are statically generating, having this property set to false will return a 404 if you try to query any URL that is outside of the array we provide in &lt;code&gt;paths&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Enabling the &lt;code&gt;fallback&lt;/code&gt; property has numerous applications and can be used in combination with &lt;code&gt;Incremental Static Generation&lt;/code&gt; which is a very powerful option within NextJS, for more information on this topic &lt;a href="https://nextjs.org/docs/basic-features/data-fetching#getstaticpaths-static-generation" rel="noopener noreferrer"&gt;see official documentation&lt;/a&gt;&lt;/p&gt;

&lt;h4&gt;
  
  
  Article data
&lt;/h4&gt;

&lt;p&gt;Within the specific article, we need to retrieve the data, for this we will consult the dev.to API using the same &lt;code&gt;slug&lt;/code&gt; with which we have built the URL.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;getStaticProps&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;async &lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="nx"&gt;params&lt;/span&gt; &lt;span class="p"&gt;})&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;devDotToPost&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nf"&gt;fetch&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="s2"&gt;`https://dev.to/api/articles/&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;process&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;env&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;DEV_USERNAME&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;/&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;params&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;slug&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;`&lt;/span&gt;
  &lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;res&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;devDotToPost&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;json&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="na"&gt;props&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="na"&gt;devDotToPost&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;res&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="p"&gt;},&lt;/span&gt;
  &lt;span class="p"&gt;};&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;All the data that comes from the dev.to API is passed in build time to the page of the specific article, this data will be accessible through the &lt;code&gt;prop&lt;/code&gt; &lt;code&gt;devDotToPost&lt;/code&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="k"&gt;default&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;Post&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="nx"&gt;devDotToPost&lt;/span&gt; &lt;span class="p"&gt;})&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="p"&gt;...&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h4&gt;
  
  
  Style the markdown
&lt;/h4&gt;

&lt;p&gt;Once we have the data of the article, among the multiple fields that come to us from the API, the content in markdown is in &lt;code&gt;body_html&lt;/code&gt;, to use it:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;div&lt;/span&gt; &lt;span class="nx"&gt;className&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;markdown&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="nx"&gt;dangerouslySetInnerHTML&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{{&lt;/span&gt; &lt;span class="na"&gt;__html&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;body_html&lt;/span&gt; &lt;span class="p"&gt;}}&lt;/span&gt; &lt;span class="sr"&gt;/&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In the &lt;code&gt;markdown&lt;/code&gt; class you must define how you want the elements look, since the API returns a raw version of the markdown. In the &lt;a href="https://github.com/dastasoft/dev-cms-static-blog/blob/master/styles/index.css" rel="noopener noreferrer"&gt;example project&lt;/a&gt; you have available a simple proposal.&lt;/p&gt;

&lt;h4&gt;
  
  
  Complete [slug].js
&lt;/h4&gt;

&lt;p&gt;This is how our template looks like for any article, you can see it directly in the &lt;a href="https://github.com/dastasoft/dev-cms-static-blog/blob/master/pages/blog/posts/%5Bslug%5D.js" rel="noopener noreferrer"&gt;repo&lt;/a&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;Head&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;next/head&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;Link&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;next/link&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;TopButton&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;../../../components/TopButton&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="k"&gt;default&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;Post&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="nx"&gt;devDotToPost&lt;/span&gt; &lt;span class="p"&gt;})&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;title&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="nx"&gt;published_at&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="nx"&gt;social_image&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="nx"&gt;body_html&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="nx"&gt;user&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="nx"&gt;type_of&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="nx"&gt;description&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="nx"&gt;canonical_url&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;devDotToPost&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;date&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Date&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;published_at&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;formatedDate&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;`&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;date&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;getDate&lt;/span&gt;&lt;span class="p"&gt;()}&lt;/span&gt;&lt;span class="s2"&gt;/&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;
    &lt;span class="nf"&gt;parseInt&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;date&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;getMonth&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt; &lt;span class="mi"&gt;10&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;/&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;date&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;getFullYear&lt;/span&gt;&lt;span class="p"&gt;()}&lt;/span&gt;&lt;span class="s2"&gt;`&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

  &lt;span class="k"&gt;return &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;div&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
      &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;Head&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
        &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;meta&lt;/span&gt; &lt;span class="nx"&gt;property&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;og:type&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="nx"&gt;content&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;type_of&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="sr"&gt;/&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;        &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;meta&lt;/span&gt; &lt;span class="nx"&gt;property&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;og:title&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="nx"&gt;content&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;title&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="sr"&gt;/&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;        &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;meta&lt;/span&gt; &lt;span class="nx"&gt;property&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;og:description&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="nx"&gt;content&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;description&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="sr"&gt;/&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;        &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;meta&lt;/span&gt; &lt;span class="nx"&gt;property&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;og:image&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="nx"&gt;content&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;social_image&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="sr"&gt;/&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;        &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;meta&lt;/span&gt; &lt;span class="nx"&gt;property&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;og:url&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="nx"&gt;content&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;canonical_url&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="sr"&gt;/&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;      &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/Head&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;      &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;div&lt;/span&gt; &lt;span class="nx"&gt;className&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;flex justify-center&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
        &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;TopButton&lt;/span&gt; &lt;span class="o"&gt;/&amp;gt;&lt;/span&gt;
        &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;article&lt;/span&gt; &lt;span class="nx"&gt;className&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;text-xs w-full md:w-3/4 &lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
          &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;div&lt;/span&gt; &lt;span class="nx"&gt;className&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;border-2 text-black bg-white md:rounded-lg overflow-hidden&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
            &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;img&lt;/span&gt; &lt;span class="nx"&gt;className&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;w-full&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="nx"&gt;src&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;social_image&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="nx"&gt;alt&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;title&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="sr"&gt;/&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;            &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;div&lt;/span&gt; &lt;span class="nx"&gt;className&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;p-4 md:p-32&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
              &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;h1&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;title&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/h1&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;              &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;div&lt;/span&gt; &lt;span class="nx"&gt;className&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;flex items-center text-gray-600&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
                &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;img&lt;/span&gt;
                  &lt;span class="nx"&gt;className&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;rounded-full w-12&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;
                  &lt;span class="nx"&gt;src&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;user&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;profile_image_90&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
                  &lt;span class="nx"&gt;alt&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;user&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;name&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
                &lt;span class="sr"&gt;/&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;                &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;span&lt;/span&gt; &lt;span class="nx"&gt;className&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;mx-4&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;user&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;name&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/span&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;                &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;span&lt;/span&gt; &lt;span class="nx"&gt;className&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;text-sm&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;formatedDate&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/span&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;              &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/div&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;              &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;div&lt;/span&gt;
                &lt;span class="nx"&gt;className&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;markdown&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;
                &lt;span class="nx"&gt;dangerouslySetInnerHTML&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{{&lt;/span&gt; &lt;span class="na"&gt;__html&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;body_html&lt;/span&gt; &lt;span class="p"&gt;}}&lt;/span&gt;
              &lt;span class="sr"&gt;/&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;            &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/div&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;          &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/div&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;          &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;Link&lt;/span&gt; &lt;span class="nx"&gt;href&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;/blog&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
            &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;a&lt;/span&gt; &lt;span class="nx"&gt;className&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;text-blue-500 inline-flex items-center md:mb-2 lg:mb-0 cursor-pointer text-base pb-8&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
              &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;svg&lt;/span&gt;
                &lt;span class="nx"&gt;className&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;w-4 h-4 mr-2&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;
                &lt;span class="nx"&gt;stroke&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;currentColor&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;
                &lt;span class="nx"&gt;strokeWidth&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;2&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;
                &lt;span class="nx"&gt;fill&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;none&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;
                &lt;span class="nx"&gt;strokeLinecap&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;round&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;
                &lt;span class="nx"&gt;strokeLinejoin&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;round&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;
                &lt;span class="nx"&gt;viewBox&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;0 0 24 24&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;
              &lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
                &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;path&lt;/span&gt; &lt;span class="nx"&gt;d&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;M19 12H5M12 19l-7-7 7-7&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="o"&gt;/&amp;gt;&lt;/span&gt;
              &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/svg&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;              &lt;span class="nx"&gt;Back&lt;/span&gt;
            &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/a&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;          &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/Link&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;        &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/article&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;      &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/div&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;    &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/div&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;  &lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;getStaticProps&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;async &lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="nx"&gt;params&lt;/span&gt; &lt;span class="p"&gt;})&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;devDotToPost&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nf"&gt;fetch&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="s2"&gt;`https://dev.to/api/articles/&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;process&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;env&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;DEV_USERNAME&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;/&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;params&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;slug&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;`&lt;/span&gt;
  &lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;res&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;devDotToPost&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;json&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="na"&gt;props&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="na"&gt;devDotToPost&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;res&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="p"&gt;},&lt;/span&gt;
  &lt;span class="p"&gt;};&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;getStaticPaths&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;devDotToPosts&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nf"&gt;fetch&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="s2"&gt;`https://dev.to/api/articles?username=&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;process&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;env&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;DEV_USERNAME&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;`&lt;/span&gt;
  &lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;posts&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;devDotToPosts&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;json&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="na"&gt;paths&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;posts&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;map&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;post&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="na"&gt;params&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
          &lt;span class="na"&gt;slug&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;post&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;slug&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="p"&gt;},&lt;/span&gt;
      &lt;span class="p"&gt;};&lt;/span&gt;
    &lt;span class="p"&gt;}),&lt;/span&gt;
    &lt;span class="na"&gt;fallback&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="p"&gt;};&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Layout
&lt;/h3&gt;

&lt;p&gt;To create the layout and apply it to all the screens, we will create it in the &lt;code&gt;_app.js&lt;/code&gt; file and internally NextJS will add it to all the pages:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;Link&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;next/link&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;../styles/index.css&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="k"&gt;default&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;App&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="nx"&gt;Component&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;pageProps&lt;/span&gt; &lt;span class="p"&gt;})&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;return &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;div&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
      &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;nav&lt;/span&gt; &lt;span class="nx"&gt;className&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;p-4 flex justify-center items-center mb-4&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="nx"&gt;id&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;nav&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
        &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;Link&lt;/span&gt; &lt;span class="nx"&gt;href&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;/&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
          &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;span&lt;/span&gt; &lt;span class="nx"&gt;className&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;text-xl font-bold cursor-pointer mr-4&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="nx"&gt;Home&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/span&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;        &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/Link&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;        &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;Link&lt;/span&gt; &lt;span class="nx"&gt;href&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;/blog&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
          &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;span&lt;/span&gt; &lt;span class="nx"&gt;className&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;text-xl font-bold cursor-pointer&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="nx"&gt;Blog&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/span&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;        &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/Link&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;      &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/nav&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;      &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;main&lt;/span&gt; &lt;span class="nx"&gt;className&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;container px-5 mx-auto&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
        &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;Component&lt;/span&gt; &lt;span class="p"&gt;{...&lt;/span&gt;&lt;span class="nx"&gt;pageProps&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="sr"&gt;/&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;      &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/main&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;    &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/div&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;  &lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The important thing at this point is:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Use the NextJS &lt;code&gt;Link&lt;/code&gt; component to make the navigation correct&lt;/li&gt;
&lt;li&gt;It is the ideal place to import the css file and apply it globally.&lt;/li&gt;
&lt;li&gt;Be sure to have &lt;code&gt;&amp;lt;Component {...pageProps} /&amp;gt;&lt;/code&gt; since without this we will not see the children components, (similar to the use of &lt;code&gt;children&lt;/code&gt; in React)&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Home
&lt;/h3&gt;

&lt;p&gt;Defining the main page in NextJS is as simple as creating the file &lt;code&gt;index.js&lt;/code&gt; inside the &lt;code&gt;pages&lt;/code&gt; folder and NextJS will automatically create a path, in this case to &lt;code&gt;/&lt;/code&gt;, which will mix what we have defined in the &lt;code&gt;_app.js&lt;/code&gt; file plus the &lt;code&gt;index.js&lt;/code&gt; itself.&lt;/p&gt;

&lt;p&gt;This is the proposed home page for the project:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;DevDotToLogo&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;../public/devdotto.svg&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;NextLogo&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;../public/nextjs.svg&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="k"&gt;default&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;Home&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;return &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;div&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
      &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;div&lt;/span&gt; &lt;span class="nx"&gt;className&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;flex justify-center items-center&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
        &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;a&lt;/span&gt;
          &lt;span class="nx"&gt;href&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;https://nextjs.org/&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;
          &lt;span class="nx"&gt;target&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;_blank&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;
          &lt;span class="nx"&gt;rel&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;noopener noreferrer&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;
          &lt;span class="nx"&gt;aria&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="nx"&gt;label&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;NextJS&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;
        &lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
          &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;NextLogo&lt;/span&gt; &lt;span class="nx"&gt;className&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;mr-4&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="nx"&gt;width&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;100px&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="nx"&gt;height&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;100px&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="o"&gt;/&amp;gt;&lt;/span&gt;
        &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/a&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;        &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;span&lt;/span&gt; &lt;span class="nx"&gt;className&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;text-2xl&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="nx"&gt;Blog&lt;/span&gt; &lt;span class="nx"&gt;Boilerplate&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/span&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;      &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/div&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;
      &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;div&lt;/span&gt; &lt;span class="nx"&gt;className&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;flex justify-center items-center&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
        &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;span&lt;/span&gt; &lt;span class="nx"&gt;className&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;text-2xl&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="kd"&gt;with&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/span&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;        &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;a&lt;/span&gt;
          &lt;span class="nx"&gt;href&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;https://dev.to/&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;
          &lt;span class="nx"&gt;target&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;_blank&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;
          &lt;span class="nx"&gt;rel&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;noopener noreferrer&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;
          &lt;span class="nx"&gt;aria&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="nx"&gt;label&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Dev.to&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;
        &lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
          &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;DevDotToLogo&lt;/span&gt; &lt;span class="nx"&gt;className&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;mx-4&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="nx"&gt;width&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;100px&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="nx"&gt;height&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;100px&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="o"&gt;/&amp;gt;&lt;/span&gt;
        &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/a&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;        &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;span&lt;/span&gt; &lt;span class="nx"&gt;className&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;text-2xl&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="nx"&gt;a&lt;/span&gt; &lt;span class="nx"&gt;CMS&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/span&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;      &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/div&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;    &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/div&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;  &lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In this case normal &lt;code&gt;anchor&lt;/code&gt; is used as they are links to the outside and NextJS does not have to access any internal route.&lt;/p&gt;

&lt;h3&gt;
  
  
  CSS
&lt;/h3&gt;

&lt;p&gt;NextJS will display errors if you try to introduce CSS that can affect globally outside the &lt;code&gt;_app.js&lt;/code&gt; file, in the other sites as pages and / or components is advisable to use solutions such as &lt;code&gt;emotionjs&lt;/code&gt;, &lt;code&gt;styled-components&lt;/code&gt;, &lt;code&gt;css-modules&lt;/code&gt; or &lt;code&gt;tailwindcss&lt;/code&gt; as in this guide, which have their scope limited to the component itself.&lt;/p&gt;

&lt;p&gt;NextJS provides its own &lt;code&gt;CSS-in-JS&lt;/code&gt; solution called &lt;code&gt;styled-jsx&lt;/code&gt; but lately from NextJS own quick-start projects it has been decided to implement &lt;code&gt;css-modules&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;If you want to know better what options you have for style issues you can check &lt;a href="https://dev.to/dastasoft/styling-in-react-4fbj"&gt;my style guide in React&lt;/a&gt; which applies mostly to NextJS, the main difference is that we can not apply global styles as we discussed above.&lt;/p&gt;

&lt;h1&gt;
  
  
  Deployment
&lt;/h1&gt;

&lt;p&gt;We will deploy this project on the platform of the same creators of NextJS which is &lt;a href="https://vercel.com/" rel="noopener noreferrer"&gt;Vercel&lt;/a&gt;. To deploy a project in Vercel you must follow the next steps:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Create a Vercel account&lt;/li&gt;
&lt;li&gt;Click on &lt;code&gt;Import Project&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;We'll import the project directly from our Git repository&lt;/li&gt;
&lt;li&gt;Provide the URL of the GIT repository&lt;/li&gt;
&lt;li&gt;In case the previous step gives you the error: &lt;code&gt;Couldn't find the Git repository. If it exists, verify that the GitHub Integration is permitted to access it in the GitHub App Settings.&lt;/code&gt; click on &lt;code&gt;GitHub App Settings&lt;/code&gt; and add the repository you're trying to deploy to Vercel's access list, if it's the first deployment you do it, Vercel will ask you for access as part of the process.&lt;/li&gt;
&lt;li&gt;Once Vercel has visibility into the Git repository, you can give it a name, a &lt;code&gt;framework preset&lt;/code&gt; that you leave as it is in Next.js, &lt;code&gt;Build and Output Settings&lt;/code&gt; that you don't need to change for now, and finally &lt;code&gt;Environment Variables&lt;/code&gt; that you create in &lt;code&gt;.env.development&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Inside &lt;code&gt;Environment Variables&lt;/code&gt; we define the variable &lt;code&gt;DEV_USERNAME&lt;/code&gt; with the value of the user about whom you want to make the queries, in my case &lt;code&gt;dastasoft&lt;/code&gt; and press &lt;code&gt;Add&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;Press &lt;code&gt;Deploy&lt;/code&gt;.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;It is possible that the first time the deployment failed giving errors of receiving wrong JSON answers, in my case trying the deployment a second time worked without problems.&lt;/p&gt;

&lt;p&gt;You can see the final result by deploying the boilerplate we have built in this tutorial at &lt;a href="https://dev-cms-static-blog.vercel.app/" rel="noopener noreferrer"&gt;https://dev-cms-static-blog.vercel.app/&lt;/a&gt;&lt;/p&gt;

&lt;h1&gt;
  
  
  Automatic update
&lt;/h1&gt;

&lt;p&gt;We're almost done, but the most important step is missing, right now we have a blog that is generated in a static way at build time, that means that when the project is deployed in Vercel, all the necessary queries are launched to dev.to to obtain the necessary information and with that a totally static website is built in which no matter how many visits we have, dev.to is not consulted again to retrieve articles.&lt;/p&gt;

&lt;p&gt;But what if we publish/edit an article? We need a way to tell Vercel that it must go back to that build phase and recover the most updated information, for that we will use webhooks.&lt;/p&gt;

&lt;h2&gt;
  
  
  Create a URL to access the display
&lt;/h2&gt;

&lt;p&gt;Within the project in Vercel, we must go to &lt;code&gt;Settings&lt;/code&gt; to the section referring to &lt;code&gt;Git&lt;/code&gt; and look for the box &lt;code&gt;Deploy Hooks&lt;/code&gt;, here we will create a new hook to which we can give the name that we want and that this in our main branch of git, in my case:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Name: dev.to&lt;/li&gt;
&lt;li&gt;Git Branch Name: master&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This will generate a URL of the type &lt;code&gt;https://api.vercel.com/v1/integrations/deploy/xxxxxxxxxxxxxxxxxxx&lt;/code&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Create webhooks on dev.to
&lt;/h2&gt;

&lt;p&gt;In the &lt;code&gt;README.md&lt;/code&gt; of the &lt;a href="https://github.com/dastasoft/dev-cms-static-blog/blob/master/README.md" rel="noopener noreferrer"&gt;boilerplate&lt;/a&gt; you have the commands available to view, create and delete webhooks in your dev.to account.&lt;/p&gt;

&lt;p&gt;You will need access to a Terminal and curl package, in your dev.to account you will need to create a dev.to API Key, this can be done by logging into dev.to with your account in the &lt;code&gt;Settings&lt;/code&gt;, &lt;code&gt;Account&lt;/code&gt; and &lt;code&gt;Dev API Keys&lt;/code&gt; section.&lt;/p&gt;

&lt;p&gt;To create the DEV API Key you have to provide a name and click on &lt;code&gt;Generate API Key&lt;/code&gt;, this will generate a hash that we will need in the following commands.&lt;/p&gt;

&lt;p&gt;With a terminal open we use the following command to create the webhook in our dev.to account&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;curl &lt;span class="nt"&gt;-X&lt;/span&gt; POST &lt;span class="nt"&gt;-H&lt;/span&gt; &lt;span class="s2"&gt;"Content-Type: application/json"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-H&lt;/span&gt; &lt;span class="s2"&gt;"api-key: API_KEY"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-d&lt;/span&gt; &lt;span class="s1"&gt;'{"webhook_endpoint":{"target_url":"TARGET_URL","source":"DEV","events":["article_created", "article_updated"]}}'&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  https://dev.to/api/webhooks
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Where &lt;code&gt;API_KEY&lt;/code&gt; is the DEV API Key that we have created in dev.to and &lt;code&gt;TARGET_URL&lt;/code&gt; (important to keep the ") is the display access URL that we have created in &lt;code&gt;Deploy Hooks&lt;/code&gt; from Vercel. In this example we are using the webhook for the events of creation of articles and also for the edition, you can leave the events that you need.&lt;/p&gt;

&lt;h2&gt;
  
  
  Check webhook
&lt;/h2&gt;

&lt;p&gt;In a terminal with curl available, execute the following command:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;curl &lt;span class="nt"&gt;-H&lt;/span&gt; &lt;span class="s2"&gt;"api-key: API_KEY"&lt;/span&gt; https://dev.to/api/webhooks
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Where &lt;code&gt;API_KEY&lt;/code&gt; is the DEV API Key we have created on dev.to.&lt;/p&gt;

&lt;p&gt;The service must answer us with an array which must not be empty, because in the previous step we created a webhook. If you get an empty array in response, check the previous step.&lt;/p&gt;

&lt;h1&gt;
  
  
  Conclusion
&lt;/h1&gt;

&lt;p&gt;If the webhook has been successfully created, what we will have achieved is that every time an article is created or edited (depending on the events you have used) it will call the URL we have provided it with, this URL will trigger a new build in Vercel that will again check the dev.to API and find the new article generating again a totally static version of our blog.&lt;/p&gt;

&lt;p&gt;With this we would have already completed the requirements that we had set at the beginning of this tutorial! I encourage you to investigate further in the project &lt;a href="https://github.com/dastasoft/dev-cms-static-blog" rel="noopener noreferrer"&gt;boilerplate&lt;/a&gt; on which this tutorial is based so that you can use it as a basis for future projects.&lt;/p&gt;

&lt;p&gt;Now it's your turn, what is your experience creating blogs? Do you think it's easier the way you're currently doing it or with this form? You already used this form or a similar one, tell me your success story or your questions :D&lt;/p&gt;

&lt;p&gt;Hopefully, this post will create a new entry in &lt;a href="https://nimbel.net/blog" rel="noopener noreferrer"&gt;Nimbel's Blog&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Enjoy!&lt;/p&gt;

</description>
      <category>nextjs</category>
      <category>react</category>
      <category>javascript</category>
      <category>english</category>
    </item>
    <item>
      <title>How much money do you lose for every second it takes to load your web application?</title>
      <dc:creator>rubenofen</dc:creator>
      <pubDate>Wed, 07 Oct 2020 13:46:23 +0000</pubDate>
      <link>https://dev.to/nimbel/how-much-money-do-you-lose-for-every-second-it-takes-to-load-your-web-application-5f4i</link>
      <guid>https://dev.to/nimbel/how-much-money-do-you-lose-for-every-second-it-takes-to-load-your-web-application-5f4i</guid>
      <description>&lt;p&gt;Did you know that most people who have a profitable business idea, fail miserably just because they &lt;strong&gt;not&lt;/strong&gt; make a reasonable investment in their sales tool?&lt;/p&gt;

&lt;p&gt;This is absolutely true and we have done an experiment in which it is confirmed that an incorrect decision can make you lose thousands of euros.&lt;/p&gt;

&lt;p&gt;Many times when we create a business, we realize that one of the most important sales channels is the internet and at that moment we decide to create our own &lt;strong&gt;web application&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Usually we have to take many decisions and make important investments in different areas so that our product or service goes ahead. &lt;/p&gt;

&lt;p&gt;The first problem we face when creating the web application is: &lt;br&gt;
**How many technologies do we have available and what are their costs? &lt;/p&gt;

&lt;p&gt;One of the technologies that entrepreneurs usually use is a CMS such as Wordpress, Joomla or Drupal, this is a very flexible solution and *&lt;em&gt;quite good&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;It allows the entrepreneur to manage their own content, maintain it and modify it, in addition many companies offer to provide hosting or hosting for Wordpress with everything pre-configured.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--_3ZBqmle--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/gdc1gquavurrkcnjmqzb.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--_3ZBqmle--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/gdc1gquavurrkcnjmqzb.jpg" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;There are also many developers of these CMS's that offer their services at a very competitive price...but...&lt;/p&gt;

&lt;p&gt;This hides a deeper problem that can turn the business into a ruin. **You have to take into account the user's behavior.&lt;/p&gt;

&lt;p&gt;According to a report from &lt;a href="https://www2.deloitte.com/content/dam/Deloitte/ie/Documents/Consulting/Milliseconds_Make_Millions_report.pdf"&gt;Deloitte&lt;/a&gt;, if your web application takes between 1 and 3 seconds to load the probability of bouncing increases by 32%, but if the loading time is in the range of 1 to 5 seconds, the probability of bouncing increases by up to 90% 😱.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--mkVOCBo_--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/m0n2cl8vh95nrh7mo7g3.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--mkVOCBo_--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/m0n2cl8vh95nrh7mo7g3.png" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  And what is the probability of rebound?
&lt;/h2&gt;

&lt;p&gt;It is considered a rebound when a user enters a website and without interacting with it closes it because he is not interested in what is on it.&lt;br&gt;
This is quite normal, because it's impossible to attract only users who are interested in your product or service to your website.&lt;br&gt;
And what effect does it have on the business to increase the likelihood of a bounce because it takes a few seconds to load?&lt;/p&gt;

&lt;h2&gt;
  
  
  The experiment
&lt;/h2&gt;

&lt;p&gt;Let's make the following assumption:&lt;br&gt;
An entrepreneur has a business where he sells a service or an article for 100 ?, of this article 50 ? are costs and the other 50 ? are benefits.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Sales price&lt;/th&gt;
&lt;th&gt;Costs&lt;/th&gt;
&lt;th&gt;Profit&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;100€&lt;/td&gt;
&lt;td&gt;50€&lt;/td&gt;
&lt;td&gt;50€&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Let's imagine that you manage to attract 4,500 users per month and if your application loaded instantly that's how users would behave:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Visits&lt;/th&gt;
&lt;th&gt;% bounce&lt;/th&gt;
&lt;th&gt;users bounce&lt;/th&gt;
&lt;th&gt;Conversion ratio&lt;/th&gt;
&lt;th&gt;Profit per month&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;4.500&lt;/td&gt;
&lt;td&gt;29%&lt;/td&gt;
&lt;td&gt;1.305&lt;/td&gt;
&lt;td&gt;2%&lt;/td&gt;
&lt;td&gt;3.195€&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;In other words, of the total of 4,500 visits, 1,305 enter but instantly realize that they are not interested and leave without interacting and reading practically nothing.&lt;/p&gt;

&lt;p&gt;For both scenarios we propose a web application that will be working &lt;strong&gt;for 3 years&lt;/strong&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  Scenario A
&lt;/h3&gt;

&lt;p&gt;The entrepreneur hires the development of a wordpress because he is convinced by the budget and the solution is already quite good, &lt;strong&gt;"I don't need that much "&lt;/strong&gt;.&lt;/p&gt;

&lt;h4&gt;
  
  
  Budget:
&lt;/h4&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Development&lt;/th&gt;
&lt;th&gt;Plugins&lt;/th&gt;
&lt;th&gt;Hosting/month(VPS)&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;1.200€&lt;/td&gt;
&lt;td&gt;300€&lt;/td&gt;
&lt;td&gt;70€&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Therefore: 1,200 + 300 + (70*3*12) = &lt;strong&gt;4,020&lt;/strong&gt; in the 3 years&lt;/p&gt;

&lt;h3&gt;
  
  
  Scenario A
&lt;/h3&gt;

&lt;p&gt;The entrepreneur hires the development of a wordpress because he is convinced by the budget and the solution is already quite good, &lt;strong&gt;"I don't need that much "&lt;/strong&gt;.&lt;/p&gt;

&lt;h4&gt;
  
  
  Budget:
&lt;/h4&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Development&lt;/th&gt;
&lt;th&gt;Plugins&lt;/th&gt;
&lt;th&gt;Hosting/month(VPS)&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;1.200€&lt;/td&gt;
&lt;td&gt;300€&lt;/td&gt;
&lt;td&gt;70€&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Therefore: 1,200 + 300 + (70*3*12) = &lt;strong&gt;4,020&lt;/strong&gt; in the 3 years&lt;/p&gt;

&lt;h4&gt;
  
  
  Result
&lt;/h4&gt;

&lt;p&gt;We have obtained this result from one of our clients, who has his product developed in wordpress and has the page hosted in a quality VPS, obviously we hide his brand so as not to damage his image.&lt;br&gt;
We will look at the First Contenful Paint, which is the time that passes from the request of the page until the first piece of content that appears on your screen, either an image, an icon or some text.&lt;br&gt;
&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--5RakvQtY--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/h9368in2efowuil5pkpb.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--5RakvQtY--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/h9368in2efowuil5pkpb.png" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;7 seconds&lt;/strong&gt; 😱😨😰😥😓. If we look at Deloitte's graph, taking between 1 and 7 seconds to load means a 123% higher probability of rebound. And how do your business results look?&lt;/p&gt;

&lt;p&gt;The original bounce was 1,305 users out of 4,500, by increasing the bounce probability by 123% we will have 2,910 users that will bounce without buying anything. With this you only have 1,519 possible buyers left. **At this point, we could evaluate the cost of having attracted traffic to your website, but we'll leave that for another article.&lt;/p&gt;

&lt;p&gt;Numbers:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Visits&lt;/th&gt;
&lt;th&gt;Bounces&lt;/th&gt;
&lt;th&gt;Interested parties&lt;/th&gt;
&lt;th&gt;Conversion ratio&lt;/th&gt;
&lt;th&gt;Sales&lt;/th&gt;
&lt;th&gt;Monthly profit&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;4.500&lt;/td&gt;
&lt;td&gt;2.910&lt;/td&gt;
&lt;td&gt;1.590&lt;/td&gt;
&lt;td&gt;2%&lt;/td&gt;
&lt;td&gt;3.179,70€&lt;/td&gt;
&lt;td&gt;1.589,85€&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h3&gt;
  
  
  Scenario B
&lt;/h3&gt;

&lt;p&gt;The entrepreneur hires the JAMSTACK development a little more expensive but that has convinced him more, because he has been assured that his page will go at the speed of light and that will have a positive impact on his business. In addition, with the traffic that the hosting has, it is &lt;strong&gt;free&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Quotation:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Professional Designer&lt;/th&gt;
&lt;th&gt;Development&lt;/th&gt;
&lt;th&gt;Hosting/month(VPS)&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;1.200€&lt;/td&gt;
&lt;td&gt;4.000€&lt;/td&gt;
&lt;td&gt;0€&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Therefore: 1,200 + 300 + (0*3*12) = &lt;strong&gt;5,200&lt;/strong&gt; in the 3 years (if clearly &lt;strong&gt;30% more expensive&lt;/strong&gt; in the 3 years)&lt;/p&gt;

&lt;h3&gt;
  
  
  Let's see stage B
&lt;/h3&gt;

&lt;p&gt;Here we expose our website directly, hosted in vercel.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--f9Brogio--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/y369dz188d1bq5u3ceeo.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--f9Brogio--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/y369dz188d1bq5u3ceeo.png" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;If we look at the image, 0.9s 🧐🤓😎🥳😏, a priori, has no bounce percentage penalty so the numbers setting up a business with a page with the JamStack stack would look like this.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Visits&lt;/th&gt;
&lt;th&gt;Bounces&lt;/th&gt;
&lt;th&gt;Interested users&lt;/th&gt;
&lt;th&gt;Conversion ratio&lt;/th&gt;
&lt;th&gt;Sales&lt;/th&gt;
&lt;th&gt;Profit month&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;4.500&lt;/td&gt;
&lt;td&gt;1.305&lt;/td&gt;
&lt;td&gt;3.195&lt;/td&gt;
&lt;td&gt;2%&lt;/td&gt;
&lt;td&gt;6.390,00€&lt;/td&gt;
&lt;td&gt;3.195,00€&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;We believe that the difference is more than noticeable, between 1,589 and 3,195 there are &lt;strong&gt;1,606&lt;br&gt;
Have you thought what you can do with that extra money a month? The car of your dreams? The little house in the mountain? or even leave your job for good, if you are a part-time entrepreneur? **Those 1600 euros change everything.&lt;/strong&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  What happened after 3 years?
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Scenario A
&lt;/h3&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Total benefits&lt;/th&gt;
&lt;th&gt;Web development&lt;/th&gt;
&lt;th&gt;Final result&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;57.234,60€&lt;/td&gt;
&lt;td&gt;4.020€&lt;/td&gt;
&lt;td&gt;53.214,60€&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h3&gt;
  
  
  Scenario B
&lt;/h3&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Total benefits&lt;/th&gt;
&lt;th&gt;Web development&lt;/th&gt;
&lt;th&gt;Final result&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;115.020,00€&lt;/td&gt;
&lt;td&gt;5.200€&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;109.820,00€&lt;/strong&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--YKR1iAPt--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/sax5c03pam2x64es91r6.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--YKR1iAPt--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/sax5c03pam2x64es91r6.jpg" alt="Alt text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Image from &lt;a href="https://pixabay.com/es/users/StartupStockPhotos-690514/?utm_source=link-attribution&amp;amp;utm_medium=referral&amp;amp;utm_campaign=image&amp;amp;utm_content=593313"&gt;StartupStockPhotos&lt;/a&gt; in &lt;a href="https://pixabay.com/es/?utm_source=link-attribution&amp;amp;utm_medium=referral&amp;amp;utm_campaign=image&amp;amp;utm_content=593313"&gt;Pixabay&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;That's more than 50,000 euros. Have you thought about what it costs you to win 50,000 euros to lose it because of a wrong decision?&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--tamFW6nb--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/oraazbu1i1pkrx778y30.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--tamFW6nb--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/oraazbu1i1pkrx778y30.png" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;In this experiment we have not taken into account the effect that having a professional designer who creates your own image and cares about the user experience, instead of using a template, can have. It's a summation and it goes on.&lt;/p&gt;

&lt;p&gt;Remember: **Good enough makes you poor&lt;/p&gt;

&lt;p&gt;Lucky you, at &lt;a href="https://nimbel.vercel.app/"&gt;Nimbel&lt;/a&gt; we are experts in websites, high performance applications, mobile applications and everything that software technology has to offer. &lt;br&gt;
Contact us and tell us what you want to do and we will offer you the solution that best fits your project. Your success is our mission.&lt;/p&gt;

</description>
      <category>english</category>
      <category>jamstack</category>
      <category>speed</category>
      <category>business</category>
    </item>
    <item>
      <title>¿Cuanto dinero pierdes por cada segundo que tarda en cargar tu aplicación web?</title>
      <dc:creator>rubenofen</dc:creator>
      <pubDate>Fri, 25 Sep 2020 08:41:47 +0000</pubDate>
      <link>https://dev.to/nimbel/cuanto-dinero-pierdes-por-cada-segundo-que-tarda-en-cargar-tu-aplicacion-web-2kfd</link>
      <guid>https://dev.to/nimbel/cuanto-dinero-pierdes-por-cada-segundo-que-tarda-en-cargar-tu-aplicacion-web-2kfd</guid>
      <description>&lt;p&gt;¿Sabias que la mayoría de la gente que tiene una idea rentable de negocio, fracasa estrepitosamente solo por &lt;strong&gt;no&lt;/strong&gt; hacer una inversión razonable en su herramienta de ventas?&lt;/p&gt;

&lt;p&gt;Esto es totalmente cierto y hemos hecho un experimento en el que se confirma que una decision incorrecta puede hacerte perder miles de euros.&lt;/p&gt;

&lt;p&gt;Muchas veces cuando creamos un negocio, nos damos cuenta que uno de los canales más importantes de ventas es internet y en ese momento nos decidimos a crear nuestra propia &lt;strong&gt;aplicación web&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Habitualmente tenemos que tomar muchas decisiones y hacer importantes inversiones en diferentes ámbitos para que nuestro producto o servicio salga adelante. &lt;/p&gt;

&lt;p&gt;El primer problema que se nos plantea a la hora de crear la aplicación web es: &lt;br&gt;
&lt;strong&gt;¿Cuantas tecnologías tenemos disponibles y que coste tienen?&lt;/strong&gt;. &lt;/p&gt;

&lt;p&gt;Una de las tecnologías que los emprendedores suelen usar es un CMS como Wordpress, Joomla o Drupal, esta es una solución muy flexible y &lt;strong&gt;bastante buena&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Permite al emprendedor gestionar su propio contenido, mantenerlo y modificarlo, además muchas empresas se ofrecen a facilitar el alojamiento o hosting para Wordpress con todo preconfigurado.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--_3ZBqmle--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/gdc1gquavurrkcnjmqzb.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--_3ZBqmle--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/gdc1gquavurrkcnjmqzb.jpg" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;También hay muchos desarrolladores de estos CMS que ofrecen sus servicios a un precio muy competitivo...pero...&lt;/p&gt;

&lt;p&gt;Esto esconde un problema más profundo que puede convertir el negocio en una ruina. &lt;strong&gt;Hay que tener en cuenta el comportamiento del usuario.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Según un informe de &lt;a href="https://www2.deloitte.com/content/dam/Deloitte/ie/Documents/Consulting/Milliseconds_Make_Millions_report.pdf"&gt;Deloitte&lt;/a&gt;, Si tu aplicación web tarda entre 1 y 3 segundos en cargar la probabilidad de rebote aumenta en un 32%, pero si el tiempo de carga se encuentra en el rango de entre 1 y 5 segundos, la probabilidad de rebote aumenta hasta en un 90% 😱.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--mkVOCBo_--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/m0n2cl8vh95nrh7mo7g3.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--mkVOCBo_--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/m0n2cl8vh95nrh7mo7g3.png" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  ¿Y que es la probabilidad de rebote?
&lt;/h2&gt;

&lt;p&gt;Se considera un rebote cuando un usuario entra en una web y sin interacturar con ella la cierra porque no le interesa lo que en cuentra.&lt;br&gt;
Esto es bastante normal, porque es imposible atraer a tu web sólo a usuarios que les interesa tu producto o servicio.&lt;br&gt;
¿Y que efecto tiene en el negocio aumentar la probalibilidad de rebote a causa un tardar unos segundos en cargar?&lt;/p&gt;

&lt;h2&gt;
  
  
  El experimento
&lt;/h2&gt;

&lt;p&gt;Vamos a plantear el siguiente supuesto:&lt;br&gt;
Un emprendedor tiene un negocio donde vende un servicio o un articulo por 100€, de este articulo 50€ son costes y los otros 50€ son beneficios.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Precio venta&lt;/th&gt;
&lt;th&gt;Costes&lt;/th&gt;
&lt;th&gt;Beneficio&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;100€&lt;/td&gt;
&lt;td&gt;50€&lt;/td&gt;
&lt;td&gt;50€&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Imaginemos que consigue atraer 4.500 usuarios al mes y si su aplicación cargara al instante así se comportarían los usuarios:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Visitas&lt;/th&gt;
&lt;th&gt;% de rebote&lt;/th&gt;
&lt;th&gt;usuarios rebote&lt;/th&gt;
&lt;th&gt;Ratio conversión&lt;/th&gt;
&lt;th&gt;Beneficio al mes&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;4.500&lt;/td&gt;
&lt;td&gt;29%&lt;/td&gt;
&lt;td&gt;1.305&lt;/td&gt;
&lt;td&gt;2%&lt;/td&gt;
&lt;td&gt;3.195€&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;O sea, del total de 4.500 visitas, 1.305 entran pero al instante se dan cuenta que no les interesa y salen sin interactuar y sin leer prácticamente nada.&lt;/p&gt;

&lt;p&gt;Para los dos escenarios planteamos una aplicación web que estará funcionando &lt;strong&gt;durante 3 años&lt;/strong&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  Escenario A
&lt;/h3&gt;

&lt;p&gt;El emprendedor contrata el desarrollo de un wordpress porque le convence el presupuesto y la solución ya es bastante buena, &lt;strong&gt;"No necesito tanto"&lt;/strong&gt;.&lt;/p&gt;

&lt;h4&gt;
  
  
  Presupuesto:
&lt;/h4&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Desarrollo&lt;/th&gt;
&lt;th&gt;Plugings&lt;/th&gt;
&lt;th&gt;Hosting/mes(VPS)&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;1.200€&lt;/td&gt;
&lt;td&gt;300€&lt;/td&gt;
&lt;td&gt;70€&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Por tanto: 1.200 + 300 + (70*3*12) = &lt;strong&gt;4.020€&lt;/strong&gt; en los 3 años&lt;/p&gt;

&lt;h4&gt;
  
  
  Resultado
&lt;/h4&gt;

&lt;p&gt;Este resultado lo hemos obtenido de uno de nuestros clientes, que tiene su producto desarrollado en wordpress y tiene la página alojada en un VPS de calidad, evidentemente ocultamos su marca para no dañar su imagen.&lt;br&gt;
Nos fijaremos en el First Contenful Paint, que es el tiempo que transcurre desde la solicitud de la página hasta que el primer fragmento de contenido que aparece en tu pantalla, ya sea una imagen, un icono o algún texto.&lt;br&gt;
&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--5RakvQtY--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/h9368in2efowuil5pkpb.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--5RakvQtY--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/h9368in2efowuil5pkpb.png" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;7 segundos&lt;/strong&gt; 😱😨😰😥😓. Si miramos el gráfico de Deloitte tardar entre 1 y 7 segundos en cargar implica un 123% más de probabilidad de rebote. ¿Y cómo le quedan los resultados de su negocio?&lt;/p&gt;

&lt;p&gt;El rebote original eran 1.305 usuarios de 4.500, al aumentar un 123% la probabilidad de rebote tendremos 2.910 usuarios que rebotarán sin comprar nada. Con esto sólo te quedan 1.519 posibles compradores. &lt;strong&gt;En este punto podríamos valorar el coste de haber atraido el tráfico a tu web, pero eso lo dejamos para otro artículo.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Números:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Visitas&lt;/th&gt;
&lt;th&gt;Rebotes&lt;/th&gt;
&lt;th&gt;Interesados&lt;/th&gt;
&lt;th&gt;Ratio conversión&lt;/th&gt;
&lt;th&gt;Ventas&lt;/th&gt;
&lt;th&gt;Beneficio mes&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;4.500&lt;/td&gt;
&lt;td&gt;2.910&lt;/td&gt;
&lt;td&gt;1.590&lt;/td&gt;
&lt;td&gt;2%&lt;/td&gt;
&lt;td&gt;3.179,70€&lt;/td&gt;
&lt;td&gt;1.589,85€&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h3&gt;
  
  
  Escenario B
&lt;/h3&gt;

&lt;p&gt;El emprendedor contrata el desarrollo JAMSTACK un poco más caro pero que le ha convencido más, porque le han asegurado que su página irá a la velocidad de la luz y eso repercutirá positivamente en su negocio. Además, con el tráfico que tiene el alojamiento le sale &lt;strong&gt;gratis&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Presupuesto:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Diseñador profesional&lt;/th&gt;
&lt;th&gt;Desarrollo&lt;/th&gt;
&lt;th&gt;Hosting/mes(VPS)&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;1.200€&lt;/td&gt;
&lt;td&gt;4.000€&lt;/td&gt;
&lt;td&gt;0€&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Por tanto: 1.200 + 300 + (0*3*12) = &lt;strong&gt;5.200€&lt;/strong&gt; en los 3 años (si claramente es un &lt;strong&gt;30% más caro&lt;/strong&gt; en los 3 años)&lt;/p&gt;

&lt;h3&gt;
  
  
  Veamos el escenario B
&lt;/h3&gt;

&lt;p&gt;Aquí exponemos nuestra web directamente, alojada en vercel.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--f9Brogio--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/y369dz188d1bq5u3ceeo.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--f9Brogio--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/y369dz188d1bq5u3ceeo.png" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Si miramos la imagen, 0.9s 🧐🤓😎🥳😏, a priori, no tiene penalización en el porcentaje de rebote así que los números montando un negocio con una página con el stack JamStack quedarían así.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Visitas&lt;/th&gt;
&lt;th&gt;Rebotes&lt;/th&gt;
&lt;th&gt;Usuarios interesados&lt;/th&gt;
&lt;th&gt;Ratio conversión&lt;/th&gt;
&lt;th&gt;Ventas&lt;/th&gt;
&lt;th&gt;Beneficio mes&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;4.500&lt;/td&gt;
&lt;td&gt;1.305&lt;/td&gt;
&lt;td&gt;3.195&lt;/td&gt;
&lt;td&gt;2%&lt;/td&gt;
&lt;td&gt;6.390,00€&lt;/td&gt;
&lt;td&gt;3.195,00€&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Creemos que la diferencia es más que notable, entre 1.589 y 3.195 hay &lt;strong&gt;1.606€&lt;/strong&gt;.&lt;br&gt;
¿Has pensado que puedes hacer con ese dinero extra al mes? ¿El coche de tus sueños? ¿La casita en la montaña? o incluso ¿Dejar el trabajo por cuenta ajena definitivamente?, si eres emprendedor part-time. &lt;strong&gt;Esos 1.600€ lo cambian todo.&lt;/strong&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  ¿Que ha pasado al cabo de 3 años?
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Escenario A
&lt;/h3&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Beneficios totales&lt;/th&gt;
&lt;th&gt;Desarrollo web&lt;/th&gt;
&lt;th&gt;Resultado final&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;57.234,60€&lt;/td&gt;
&lt;td&gt;4.020€&lt;/td&gt;
&lt;td&gt;53.214,60€&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h3&gt;
  
  
  Escenario B
&lt;/h3&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Beneficios totales&lt;/th&gt;
&lt;th&gt;Desarrollo web&lt;/th&gt;
&lt;th&gt;Resultado final&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;115.020,00€&lt;/td&gt;
&lt;td&gt;5.200€&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;109.820,00€&lt;/strong&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--YKR1iAPt--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/sax5c03pam2x64es91r6.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--YKR1iAPt--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/sax5c03pam2x64es91r6.jpg" alt="Alt text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Imagen de &lt;a href="https://pixabay.com/es/users/StartupStockPhotos-690514/?utm_source=link-attribution&amp;amp;utm_medium=referral&amp;amp;utm_campaign=image&amp;amp;utm_content=593313"&gt;StartupStockPhotos&lt;/a&gt; en &lt;a href="https://pixabay.com/es/?utm_source=link-attribution&amp;amp;utm_medium=referral&amp;amp;utm_campaign=image&amp;amp;utm_content=593313"&gt;Pixabay&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Son más de 50.000€. ¿Has pensado lo que te cuesta ganar 50.000€ como para perderlos por una decisión equivocada?&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--tamFW6nb--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/oraazbu1i1pkrx778y30.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--tamFW6nb--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/oraazbu1i1pkrx778y30.png" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;En este experimento no hemos tenido en cuenta el efecto que puede tener el hecho de contar con un diseñador profesional que cree tu propia imagen y se preocupe por la experiencia de usuario, en vez de usar una plantilla. Es un suma y sigue.&lt;/p&gt;

&lt;p&gt;Recuerda: &lt;strong&gt;Good enough makes you poor&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Por suerte para ti, en &lt;a href="https://nimbel.vercel.app/"&gt;Nimbel&lt;/a&gt; somos expertos en webs, aplicaciones de alto rendimiento, aplicaciones móviles y en todo lo que la tecnología del software puede ofrecerte. &lt;br&gt;
Contacta con nosotros y cuéntanos que quieres hacer y nosotros nos encargaremos de ofrecerte la solución que mejor encaje con tu proyecto. Tú éxito es nuestra misión.&lt;/p&gt;

</description>
      <category>spanish</category>
      <category>jamstack</category>
      <category>speed</category>
      <category>business</category>
    </item>
  </channel>
</rss>
