Para los desarrolladores front-end, el excelente framework de renderizado del lado del servidor (SSR) Next.js puede ser una potente incorporación a sus herramientas. Next.js ofrece una forma sencilla de crear un sitio web con contenido estático, como un portafolio o un blog. Desde el primer momento, Next.js cuenta con excelentes herramientas de creación de sitios web, incluyendo un sistema de enrutamiento de flujos de trabajo y un paquete web para crear paquetes automáticamente en segundo plano, lo que nos permite centrarnos en el contenido desde el principio.
En este tutorial de React, crearemos un blog estático. Dado que las páginas de nuestro sitio no cambian con frecuencia, no necesitamos una base de datos para almacenar las publicaciones; en su lugar, las almacenaremos estáticamente en el código fuente usando Markdown y Next.js.
Usaremos estos paquetes en nuestro proyecto:
• React : Biblioteca JS declarativa para UI
• Next.js : React isomórfico en el servidor y el navegador
• Material-UI : Diseño de interfaz de usuario magnífico y listo para usar
• MDX : “JSX en Markdown para proyectos ambiciosos”
Tutorial de React: Primeros pasos
1. Primero, crearemos un nuevo directorio para nuestro proyecto, inicializando un archivo package.json y luego instalaremos los paquetes React y Next.js:
mkdir blog-next
cd blog-next
npm init -y
npm install --save react react-dom next2. Next.js tiene su propio sistema de enrutador integrado listo para usar, por lo que solo necesitamos crear un directorio de páginas :
Páginas mkdirAñadiremos nuevas páginas como componentes React JSX a medida que construyamos más partes del sitio web
3. Continuando con la opción de biblioteca de componentes elegida ( Material-UI ), instale la biblioteca:
yarn add @material-ui/coreAhora estamos listos para crear el diseño y los nuevos componentes con Material Design
Creación del diseño del sitio web
El diseño de nuestro sitio web incluye una barra de navegación con:
• El enlace de correo a la página de inicio (título)
• Un enlace “Acerca de”
• Un título de sección para publicaciones del blog destacado
• Una cuadrícula de dos columnas que muestra tarjetas con el título, la fecha de publicación y un resumen del contenido de cada publicación.
1. Define /pages/index.jsx. Esta también será nuestra página de destino en my-domain.com/ , donde my-domain es el dominio para producción, o simplemente localhost:3000 si estamos en desarrollo.
2. Defina la página de índice de la siguiente manera:
const Index = () => {
const classes = useStyles();
return (
<React.Fragment>
<CssBaseline />
<Header />
<Container maxWidth="lg" className={classes.container}>
<Box my={4} display="flex" justifyContent="center">
<Typography variant="h4" component="h1" gutterBottom>
Entradas de blog destacadas
</Typography>
</Box>
<Grid container spacing={4}>
{blogPosts.map(post => (
<PostCard key={post.title} post={post} />
))}
</Grid>
</Container>
<Footer title="Mi blog" description="¡Hola, este es mi blog!" />
</React.Fragment>
);
};
Aquí usamos varios componentes dentro del directorio /components , como Header para el panel de navegación superior y Footer para el panel inferior. Estos componentes son relativamente pequeños y sencillos; puedes consultarlos en mi repositorio de GitHub .
El tercer componente, PostCard, y la matriz importada blogPosts , merecen una mirada más de cerca, porque son los elementos centrales del motor de microblogs.
Primero echemos un vistazo a PostCard.jsx :
const Postal = ({ publicación }) => {
const clases = useStyles();
return (
<Elemento de cuadrícula xs={12} md={6}>
<Enlace href={publicación.ruta}>
<NombreClaseDeTarjeta={clases.tarjeta}>
<div NombreClase={clases.detallesDeTarjeta}>
<ContenidoDeTarjeta>
<ComponenteTipografía="h2" variante="h5">
{publicación.título} <
/Tipografía
> <VarianteTipografía="subtítulo1" color="textoSecondary">
{publicación.publicadoEn} <
/Tipografía>
<VarianteTipografía="subtítulo1" párrafo>
{publicación.resumen} <
/Tipografía>
<VarianteTipografía="subtítulo1" color="primario">
Continuar leyendo...
</Tipografía>
</ContenidoDeTarjeta>
</div>
</Tarjeta>
</Enlace>
</Grid>
);
}Este es un componente que espera una publicación de propiedad que contenga un título, una fecha de publicación, una ruta o href y un resumen, como podemos ver en el ejemplo de diseño anterior.
Configuración de Markdown en Next.js
Debemos proporcionar de alguna manera estas propiedades de las entradas de blog que escribimos en Markdown (es decir, dentro del directorio de páginas) al componente PostCard para poder mostrar una vista previa en la página de destino. ¿Cómo? La respuesta es que, como nuestro sitio es estático, podemos leer las propiedades del sistema de archivos.
Pero primero, debemos instalar y configurar el paquete que usaremos para trabajar con Markdown: MDX , que viene listo para trabajar con Next.js.
1. Agregue next y un complemento para Next.js:
hilo agregar @next/mdx @mdx-js/loader2. Luego crea el archivo /next.config.js e incluye este contenido:
constante conMDX = require('@next/mdx')({
extensión: /\.mdx?$/
});
módulo.exports = conMDX({
pageExtensions: ['js', 'jsx', 'md', 'mdx']
});Esto le indica a Next que importe automáticamente los archivos con la extensión "md" y los procese como si fueran archivos JSX. Veremos que nuestra publicación es, en realidad, un componente JSX de React y un archivo Markdown a la vez.
Importar publicaciones de Markdown dentro de React
Ahora definimos la utilidad JavaScript para cargar las publicaciones en Markdown.
1. Crea la carpeta /data y dentro el archivo get-blog-posts.js :
const fs = require('fs');
const path = require('path');
const META = /export\s+const\s+meta\s+=\s+(\{(\n|.)*?\n\})/;
const DIR = path.join(process.cwd(), './pages/blog/');
const archivos = fs
.readdirSync(DIR)
.filter((archivo) => archivo.endsWith('.md'));
módulo.exports = archivos
.map(archivo => {
const nombre = ruta.join(DIR, archivo);
const contenido = fs.readFileSync(nombre, 'utf8');
const coincidencia = META.exec(contenido);
if (!match || typeof match[1] !== 'string')
arrojar nuevo Error(`${name} necesita exportar const meta = {}`);
constante meta = eval('(' + match[1] + ')');
devolver {
...meta,
ruta: '/blog/' + archivo.replace(/\.mdx?$/, '')
};
})
.filter((meta) => meta.published)
.sort((a, b) => nueva Fecha(b.publishedAt) - nueva Fecha(a.publishedAt));Esta función busca en la carpeta /pages/blog/ cualquier archivo con extensión .md . Dentro de cada archivo, espera un objeto llamado meta , donde residen las propiedades de la entrada (título, ruta, resumen y fecha de publicación), que es lo que la función exporta finalmente.
Veamos cómo luce una publicación de blog:
importar BlogPost desde '../../components/BlogPost';
export const meta = {
published: true,
publishedAt: '2019-01-15',
title: 'Esta es mi primera publicación de blog',
summary:
'Estoy aprendiendo a crear un blog usando Markdown en una página web estática creada sobre Next.js'
};
exportar predeterminado ({ hijos }) => <BlogPost meta={meta}>{hijos}</BlogPost>;
<<El contenido real va aquí>>El ejemplo anterior es la primera parte de una entrada en /pages/blog/my-first-post.md (tenga en cuenta que añadí un subdirectorio " blog" dentro de "pages" para separar las entradas del resto de páginas). Comienza importando un componente de React, BlogPost , que sirve de marco para el contenido del blog, como veremos en breve. Luego, tenemos el metaobjeto con los metadatos de la entrada del blog y una exportación predeterminada de este archivo JSX (un componente de React). ¡Finalmente, tenemos el contenido de la entrada! Así es como escribimos una entrada en nuestro blog. ¡Es muy sencillo y ordenado!
Manejo de recursos estáticos
Volviendo a nuestra vista previa de las publicaciones en la página de índice, deberíamos poder importar los metadatos y mostrarlos en las tarjetas
Sin embargo, dado que trabajamos con datos estáticos, debemos encontrar la manera de que la importación se realice en tiempo de compilación. Una importación normal no funcionará porque, al ejecutarse en el navegador, intentará recuperar datos del servidor. La solución es preevaluar el contenido proporcionado por get-blog-posts.js en el servidor, antes de entregarlo al cliente.
1. Para ello, utilizaremos algunos complementos disponibles en Babel: babel-plugin-macros y babel-plugin-preval :
hilo agregar --dev babel-plugin-macros babel-plugin-preval2. Agrega un archivo .babelrc y el contenido:
{
"ajustes preestablecidos": ["next/babel"],
"complementos": ["macros"]
}3. Agrega un archivo en /data/blog-posts.js (¡aquí es donde ocurre la magia!):
importar preval desde "babel-plugin-preval/macro";
módulo.exports = preval`módulo.exports = require('./get-blog-posts.js');`;La última línea preevalúa el contenido recuperado por get-blog-posts.js , por lo que en realidad estamos exportando la matriz de metaobjetos en lugar de la función para obtenerlos.
Cómo mostrar una entrada de blog como una página independiente
Por último, veamos cómo se muestra una publicación de blog:
Vemos:
• Los paneles de navegación y pie de página en la página de índice
• Un enlace «Volver al blog» en la esquina superior izquierda
• Un enlace para regresar a la página de destino
• Enlaces en la sección inferior para ir al blog anterior y/o siguiente
Para obtener los enlaces anterior/siguiente, necesitamos usar blog-posts.js aquí:
const BlogPost = ({ meta, children }) => {
const current = blogposts.map(({ title }) => title).indexOf(meta.title);
const next = blogposts[current - 1];
const prev = blogposts[current + 1];
return (
<Fragment>
<Header />
<Container maxWidth="md">
<Box my={4}>
<Link href="/">{'< '} VOLVER AL BLOG</Link>
</Box>
<Typography variant="h4" component="h1" gutterBottom>
{meta.title}
</Typography>
{children}
<hr />
<Box my={4} display="flex" justifyContent="center">
<Box mx={4}>
{prev && (
<NextPost
href={prev.path}
position="< Entrada anterior"
title={prev.title}
/>
)}
</Box>
<Box mx={4}>
{next && (
<NextPost
href={next.path}
position="Siguiente entrada >"
title={next.title}
/>
)}
</Box>
</Box>
</Container>
<Footer title="Mi blog" description="Hola, este es mi ¡blog!" />
</Fragmento>
);
};
¡Ahora tienes una nueva herramienta para sitios web simples y estáticos en tu caja de herramientas!
En este tutorial de React, creamos un blog sencillo con Markdown y Next.js. Esto ofrece muchas ventajas, entre ellas:
• Optimización SEO y reducción del tiempo de arranque mediante el uso de SSR
• Evita la necesidad de alojar una base de datos, ya que las publicaciones se almacenan en el control de origen.
• Formato de texto magnífico listo para usar con Markdown
• Implementación continua y alojamiento gratuito para su sitio web utilizando servicios como zeit.co
React está bien establecido y seguirá brillando como marco para SSR y sitios web estáticos, especialmente con la creciente popularidad de la pila JAM y herramientas como GatsbyJS y Next.js.
Ahora tienes una herramienta valiosa para crear sitios web estáticos y sencillos usando SSR en el desarrollo frontend. ¡Espero que la disfrutes!

Comentarios