Skip to content

Mi blog personal donde comparto artículos sobre mi aprendizaje y experiencia en el mundo del desarrollo de software. 👍

Notifications You must be signed in to change notification settings

TomasCuevas/whiteblack

Repository files navigation

Whiteblack — Blog de programación con Next.js + MDX

Blog técnico construido con Next.js 13, MDX y Tailwind CSS. Los artículos se escriben en MDX con frontmatter, se procesan estáticamente (SSG) y se renderizan con componentes React personalizados. Incluye SEO on-page, imágenes Open Graph dinámicas con @vercel/og, tema claro/oscuro, listado/paginación y navegación por categorías.

  • Producción estática: getStaticProps / getStaticPaths
  • Artículos en src/content/articles/*.mdx
  • Categorías en src/content/categories/*.md
  • SEO/OG centralizado en src/components/layout/LayoutHead/LayoutHead.tsx
  • OG dinámico en src/pages/api/og.tsx (Edge Runtime)
  • Theming con next-themes
  • Tailwind vía tailwind.config.js

Tabla de contenido


Tecnologías

  • Next.js 13.1 (pages router), React 18
  • MDX: gray-matter, next-mdx-remote, rehype-highlight
  • Estilos: Tailwind CSS, fuentes de Google
  • Theming: next-themes
  • OG dinámico: @vercel/og (API Edge)
  • Utilidades: reading-time, uuid, react-icons

Arquitectura y flujo

  1. Fuentes de contenido
  • Artículos: src/content/articles/*.mdx con frontmatter (ver más abajo).
  • Categorías: src/content/categories/*.md (frontmatter YAML).
  1. Transformación MDX ➜ HTML
  • src/utils/mdxArticlesTransform/mdxArticlesTransform.ts
    • getAllArticleFiles(): lista los archivos MDX.
    • getArticleFileBySlug(slug): extrae frontmatter y content con gray-matter, serializa MDX con next-mdx-remote/serialize y rehype-highlight. Calcula readingTime.
    • getAllArticleFilesMetadata(category?): compila metadatos ordenados por fecha, serializa cardDescription para previsualizaciones.
  • src/utils/mdxCategoriesTransform/mdxCategoriesTransform.ts
    • getAllCategoryFiles(), getCategoryFileBySlug(slug), getAllCategoryFilesMetadata().
  1. Renderizado
  • Artículo: src/pages/[slug].tsx renderiza con MDXRemote, aplica tema y genera sidebar de contenidos con getAllSectionsToSidebar, observers, PTagPreviousH2.
  • Listados: src/pages/index.tsx (últimos artículos), src/pages/categorias.tsx, src/pages/categoria/[category].tsx.
  1. SEO / OG
  • src/components/layout/LayoutHead/LayoutHead.tsx: meta tags Open Graph y Twitter.
  • src/pages/api/og.tsx: genera imágenes OG on-the-fly (Edge). Usa fuentes de /public/fonts y assets de /public/images.

Estructura de carpetas

  • src/content/articles/: artículos MDX.
  • src/content/categories/: categorías MD.
  • src/pages/: rutas Next.js
    • index.tsx, [slug].tsx, categorias.tsx, categoria/[category].tsx, api/og.tsx.
  • src/components/: UI y piezas de artículo
    • Artículo: ArticleHeader, ArticleFooter, ArticleCard, ArticlesFeed, ArticlesFeedByCategory.
    • Layout: MainLayout, Header, MobileSidebar, Footer, LayoutHead.
    • MDX: MDXComponents + componentes Deploy, Repository, Section, Link.
    • UI: ThemeSwitch, PaginationButtons, SectionTitle, MeCard, Icon.
  • src/utils/: transformadores MDX, sidebar, observers, etc.
  • src/styles/: estilos globales y de artículos.
  • public/images/categories/*.svg: iconos por categoría.
  • public/images/og/*.jpg: imágenes OG estáticas (home/categorías).
  • docs/: documentación complementaria (ARTICLES_METADATA.md, MDX_TO_HTML.md).

Instalación y ejecución

Requisitos: Node.js 16+ recomendado.

# instalar dependencias
npm install

# desarrollo
npm run dev

# construir producción
npm run build

# servir build
npm start

# lint
npm run lint

Variables de entorno

Crear .env.local en la raíz:

NEXT_PUBLIC_URL=https://tu-dominio.com
  • Se usa en LayoutHead para og:url, twitter:url y para resolver og:image.
  • También lo usa api/og.tsx para cargar assets (/wb.svg, /images/categories/...).

En desarrollo puedes usar http://localhost:3000, pero para OG en producción debe apuntar al dominio público.


Añadir un artículo (MDX)

  1. Crear un archivo en src/content/articles/mi-articulo.mdx con este frontmatter mínimo:
---
author: "Tu Nombre"
link: "https://tu-linkedin-o-web"
title: "Título del artículo"
date: "2023-12-31"
description: "Descripción corta para SEO."
cardDescription: "Primer párrafo o resumen que se verá en la tarjeta de listado."
category: "react" # debe existir como categoría (ver abajo)
tags:
  - "react"
  - "hooks"
keywords: "palabras, clave, separadas, por, comas"
---
  1. Escribe contenido MDX debajo. Puedes usar los componentes MDX del proyecto (ver sección correspondiente).

  2. La página del artículo se generará en /mi-articulo usando getStaticPaths/getStaticProps.

Notas:

  • readingTime se calcula automáticamente.
  • El OG del artículo se genera dinámicamente (/api/og) con título, autor, categoría, tags, fecha y tiempo de lectura.
  • Asegúrate de que category esté soportada (ver “Añadir una categoría”).

Añadir una categoría

  1. Crear src/content/categories/<categoria>.md:
---
title: Artículos sobre <Nombre>
category: <slug-categoria> # p.ej. react, javascript...
subtitle: Breve subtítulo
description: Descripción de la categoría.
---
  1. Asegurar icono en public/images/categories/<slug-categoria>.svg.

  2. Agregar color en src/data/categoryColors.ts:

export const categoryColors = {
  // ...
  "<slug-categoria>": "#rrggbbaa",
};
  1. Si es una categoría nueva no listada, añadirla al tipo ICategories en src/interfaces/category/ICategoryMetadata.ts.

La lista de categorías se ordena alfabéticamente y la página de categoría se genera en /categoria/<slug-categoria>.


Componentes MDX disponibles

Estos componentes están expuestos para usarlos dentro de los .mdx vía MDXComponents:

  • Section: bloque semántico que el sistema usa para construir el índice lateral (H2/H3).
  • Link: link estilizado con icono.
  • Repository: botón “Explorar en GitHub”.
  • Deploy: botón “Demostración en línea”.

Ejemplos:

<Section>
## Introducción

Texto...

<Link url="https://example.com">Documentación oficial</Link>
</Section>

<Repository url="https://github.com/usuario/repositorio" />

<Deploy url="https://demo.example.com" />

SEO y Open Graph

  • src/components/layout/LayoutHead/LayoutHead.tsx añade:
    • og:url, og:type, og:title, og:image, twitter:card, twitter:url, etc.
    • Usa process.env.NEXT_PUBLIC_URL + router.asPath para URLs canónicas.
  • OG dinámico (src/pages/api/og.tsx):
    • Edge Runtime.
    • Usa fuentes de /public/fonts.
    • Parámetros: title, author, category, tags, date, readingTime.
    • Los artículos configuran su image como /api/og?... automáticamente en [slug].tsx.

Home y categorías usan imágenes OG estáticas de public/images/og/.


Estilos y theming

  • Tailwind con darkMode: "class". Config extendido en tailwind.config.js (colores, breakpoints xs, mdx, sidebar, lgx, tipografías).
  • Fuentes Roboto, Merriweather e Inter se cargan en _document.tsx.
  • Theming con next-themes (ThemeProvider en _app.tsx) y el componente ThemeSwitch.
  • Estilos específicos para MDX y resaltado en src/styles/article.css, articleCard.css, articleSidebar.css + tema de highlight atom-one-dark.

Paginación y feeds

  • ArticlesFeed pagina de 4 en 4 usando el hook usePagination.
  • ArticlesFeedByCategory lista todos los artículos de la categoría sin paginar.
  • Botones de paginación en src/components/ui/PaginationButtons/PaginationButtons.tsx.

Rutas y páginas

  • /: últimos artículos (src/pages/index.tsx).
  • /[slug]: artículo individual (SSG) con índice lateral (secciones H2/H3 observadas dinámicamente).
  • /categorias: listado de categorías existentes con al menos un artículo.
  • /categoria/[category]: artículos por categoría.
  • /api/og: API Edge que devuelve imagen OG.

Licencia y autor

  • Autor: Tomás Cuevas — ver enlaces en el Footer del sitio (GitHub y LinkedIn).
  • Licencia: no especificada en el repositorio.

About

Mi blog personal donde comparto artículos sobre mi aprendizaje y experiencia en el mundo del desarrollo de software. 👍

Topics

Resources

Stars

Watchers

Forks