Crear un portfolio con Next.js y Notion API usando ISR

Next.jsNotion APIISRPortfolio

Guía paso a paso para crear un portfolio moderno con Next.js y Notion API, usando Incremental Static Regeneration (ISR) para obtener un sitio rápido, escalable y fácil de mantener.

Publicado por Felipe Giraldo


En este post quiero mostrar cómo construí mi portfolio personal usando Next.js 16, Notion como CMS headless y Incremental Static Regeneration (ISR).

La idea era simple: tener un sitio rápido, fácil de mantener y que me permitiera actualizar el contenido sin tocar código cada vez.

Este enfoque es el que actualmente uso en mi portfolio y en varios proyectos con clientes.


¿Qué vamos a construir?

Un portfolio personal con las siguientes características:

  • Next.js 16 usando App Router
    • Notion API como gestor de contenido
      • Incremental Static Regeneration (ISR)
        • TypeScript
          • Tailwind CSS
            • Despliegue en Vercel

              Prerrequisitos

              Para seguir este tutorial necesitas:

              • Node.js 18 o superior
                • pnpm (recomendado), aunque npm o yarn también funcionan
                  • Una cuenta de Notion
                    • Una cuenta de Vercel

                      Paso 1: Configuración inicial del proyecto

                      Voy a partir de un template que ya tiene la estructura base del proyecto.

                      Clonar el repositorio

                      git clone https://github.com/astrxnomo/portfolio-nextjs-notion.git
                      cd portfolio-nextjs-notion
                      pnpm install

                      Antes de ejecutar el proyecto, es necesario configurar Notion y las variables de entorno.


                      Paso 2: Usar Notion como CMS

                      Una de las razones por las que uso Notion es porque me permite actualizar contenido de forma muy cómoda, sin paneles de administración adicionales.

                      Crear la integración en Notion

                      1. Ir a Integraciones de Notion
                        1. Crear una nueva integración con el nombre Portfolio CMS
                          1. Configurarla como Internal
                            1. Copiar el token de integración

                              Ese token será nuestra clave de acceso a la API:

                              NOTION_API_KEY=tu_token_de_integracion

                              Duplicar las bases de datos

                              Para no crear todo desde cero, puedes duplicar la plantilla con las bases de datos ya configuradas:

                              Plantilla Next.js + Notion
                              astrxnomo.notion.site/Next-js-16-Notion-API-Databases-2da23bce200280069c63e34ad9f5de69?pvs=74

                              Una vez duplicada:

                              1. Abre la página en tu workspace
                                1. En los tres puntos (arriba a la derecha), entra en Conexiones
                                  1. Conecta la integración Portfolio CMS

                                    Al hacer esto, la integración tendrá acceso a todas las bases de datos dentro de esa página.


                                    Configurar el botón de actualización (ISR manual)

                                    En producción, el sitio no se actualiza automáticamente. Yo prefiero tener control total sobre cuándo publicar cambios, así que uso un botón en Notion.

                                    1. En la página duplicada, configura el botón Actualizar
                                      1. Asegúrate de que tenga la acción Enviar webhook
                                        1. Configura la URL:
                                            https://tu-dominio.vercel.app/api/revalidate
                                        2. Agrega el header personalizado:
                                            X-Notion-Secret: TU_SECRETO_WEBHOOK

                                        El secret puedes generarlo aquí: Online UUID Generator Tool

                                        En desarrollo local, este paso no es necesario.

                                        Image


                                        Paso 3: Variables de entorno

                                        Obtener los IDs de las bases de datos

                                        Para cada base de datos:

                                        1. Ábrela en Notion
                                          1. Ve a Configuración
                                            1. Entra en Gestionar fuentes de datos
                                              1. Copia el ID de la fuente
                                                Image
                                                Image

                                                Crea un archivo .env.local con lo siguiente:

                                                NOTION_API_KEY=tu_token_de_integracion
                                                NOTION_ABOUT_DB_ID=tu_id_base_about
                                                NOTION_EXPERIENCE_DB_ID=tu_id_base_experience
                                                NOTION_PROJECTS_DB_ID=tu_id_base_projects
                                                NOTION_WEBHOOK_KEY=tu_secreto_webhook

                                                Ejecutar el proyecto

                                                pnpm dev

                                                Luego abre http://localhost:3000.


                                                Paso 4: Cargar tu contenido en Notion

                                                About

                                                Aquí coloco la información personal:

                                                • Nombre
                                                  • Bio
                                                    • Ubicación
                                                      • Email
                                                        • Redes
                                                          • Skills

                                                            Experience

                                                            Uso esta base para mi experiencia laboral:

                                                            • Empresa
                                                              • Rol
                                                                • Fechas
                                                                  • Descripción
                                                                    • Enlace externo

                                                                      Projects

                                                                      Aquí agrego los proyectos que quiero mostrar:

                                                                      • Nombre
                                                                        • Descripción
                                                                          • Imágenes
                                                                            • Demo y repositorio
                                                                              • Tecnologías

                                                                                Paso 5: Despliegue en Vercel

                                                                                1. Subir el proyecto a GitHub
                                                                                  1. Importarlo en Vercel
                                                                                    1. Configurar las variables de entorno

                                                                                      Las variables son las mismas que en .env.local:

                                                                                      NOTION_API_KEY=tu_token_de_integracion
                                                                                      NOTION_ABOUT_DB_ID=tu_id_base_about
                                                                                      NOTION_EXPERIENCE_DB_ID=tu_id_base_experience
                                                                                      NOTION_PROJECTS_DB_ID=tu_id_base_projects
                                                                                      NOTION_WEBHOOK_KEY=tu_secreto_webhook
                                                                                      

                                                                                      Cómo funciona ISR en este proyecto

                                                                                      El sitio se genera de forma estática y solo se actualiza cuando yo lo decido.

                                                                                      export default async function HomePage() {
                                                                                        const { about, experience, projects } = await getData()
                                                                                      }

                                                                                      Qué gano con este enfoque

                                                                                      • Mejor rendimiento
                                                                                        • Páginas servidas desde CDN
                                                                                          • SEO completo
                                                                                            • Control total sobre publicaciones

                                                                                              Cuándo se actualiza el contenido

                                                                                              • En local: cada cambio en Notion se refleja automáticamente
                                                                                                • En producción: solo cuando presiono el botón Actualizar en Notion

                                                                                                  Personalización

                                                                                                  Estilos y colores

                                                                                                  Los estilos están centralizados en app/globals.css.

                                                                                                  También puedes usar TweakCN para ajustar el theme de Tailwind

                                                                                                  Image


                                                                                                  Agregar nuevas secciones

                                                                                                  Cuando necesito una nueva sección:

                                                                                                  1. Creo una nueva base de datos en Notion
                                                                                                    1. Agrego el fetch en lib/data/
                                                                                                      1. Creo el componente en components/sections/

                                                                                                        Problemas comunes

                                                                                                        Invalid API key

                                                                                                        • Revisa el token
                                                                                                          • Confirma que la integración sea Internal

                                                                                                            Database not found

                                                                                                            • Revisa los IDs
                                                                                                              • Asegúrate de que la base esté conectada a la integración

                                                                                                                Conclusión

                                                                                                                Este setup me permite tener un portfolio rápido, limpio y fácil de mantener, sin depender de un CMS tradicional.

                                                                                                                Notion se convierte en el panel de administración y Next.js se encarga del rendimiento.

                                                                                                                Es una base sólida que también uso para blogs, landings y sitios de clientes.

                                                                                                                En los próximos posts puedo mostrar cómo:

                                                                                                                • Convertir esto en un blog completo
                                                                                                                  • Manejar múltiples idiomas con Notion
                                                                                                                    • Usar esta arquitectura para proyectos comerciales

                                                                                                                      Si te interesa alguno de esos temas, seguimos por ahí.