Implementación de sitios web de Next.js híbridos en Azure Static Web Apps (versión preliminar)

En este tutorial, aprenderá a implementar un sitio web de Next.js en Azure Static Web Apps, para lo que usará la compatibilidad con las características de Next.js, como React Server Components, representación del lado servidor (SSR) y rutas de API.

Nota:

La compatibilidad híbrida de Next.js está en versión preliminar.

Requisitos previos

Características no admitidas en versión preliminar

Las siguientes características de Static Web Apps no se admiten para Next.js con representación híbrida:

  • API vinculadas que usan Azure Functions, Azure App Service, Azure Container Apps o Azure API Management.
  • Emulación e implementación local de SWA CLI.
  • Compatibilidad parcial con el archivo staticwebapp.config.json.
    • No se admite la reserva de navegación.
    • Las reescrituras de rutas a las rutas que se encuentran dentro de la aplicación de Next.js deben configurarse en next.config.js.
    • La configuración que se encuentra dentro del archivo staticwebapp.config.json tiene prioridad sobre la configuración dentro de next.config.js.
    • La configuración del sitio de Next.js debe controlarse mediante next.config.js para obtener una compatibilidad completa con las características.
  • skip_app_build y skip_api_build no se pueden usar en la imagen de implementación Azure/static-web-apps-deploy@v1.
  • La regeneración estática incremental (ISR) no admite el almacenamiento de imágenes en la caché.

Nota:

El tamaño máximo de la aplicación de Next.js híbrida es 250 MB. Use la característica independiente de Next.js para tamaños de aplicación optimizados. Si esto no fuera suficiente, considere la posibilidad de usar la exportación a HTML estático de Next.js si el requisito de tamaño de la aplicación es superior a 250 MB.

Creación de un repositorio

En este artículo se usa un repositorio de plantillas de GitHub para facilitar los primeros pasos. La plantilla incluye una aplicación de inicio que se implementa en Azure Static Web Apps.

  1. Vaya a la siguiente ubicación para crear un repositorio.

    https://github.com/staticwebdev/nextjs-hybrid-starter/generate

  2. Asigne el nombre my-first-static-web-app al repositorio.

  3. Seleccione Create repository from template (Crear repositorio a partir de plantilla).

    Captura de pantalla del botón Crear repositorio a partir de la plantilla.

Creación de una aplicación web estática

Ahora que se ha creado el repositorio, puede crear una aplicación web estática desde Azure Portal.

  1. Vaya a Azure Portal.
  2. Seleccione Crear un recurso.
  3. Busque Static Web Apps.
  4. Seleccione Static Web Apps.
  5. Seleccione Crear.

En la sección Aspectos básicos, configure la nueva aplicación y vincúlela a un repositorio de GitHub.

Captura de pantalla de la sección Aspectos básicos de Azure Portal.

Configuración Valor
Subscription Seleccione su suscripción a Azure.
Grupo de recursos Seleccione el vínculo Crear nuevo y escriba static-web-apps-test en el cuadro de texto.
Name Escriba my-first-static-web-app en el cuadro de texto.
Tipo de plan Seleccione Gratis.
Detalles de almacenamiento provisional y Azure Functions Seleccione la región más cercana a la suya.
Source Seleccione GitHub.

Seleccione Iniciar sesión con GitHub y autentíquese con GitHub.

Tras iniciar sesión con GitHub, escriba la información del repositorio.

Configuración Valor
Organización Seleccione su organización.
Repositorio Seleccione my-first-web-static-app.
Rama Seleccione main (principal).

Captura de pantalla de los detalles del repositorio en Azure Portal.

Nota:

Si no ve ningún repositorio:

  • Quizá deba autorizar Azure Static Web Apps en GitHub. Vaya al repositorio de GitHub y, a continuación, a Configuración > Aplicaciones > Aplicaciones de OAuth autorizadas, seleccione Azure Static Web Apps y, después, Conceder.
  • Es posible que tenga que autorizar Azure Static Web Apps en la organización de Azure DevOps. Debe ser propietario de la organización para conceder los permisos. Solicite acceso a las aplicaciones de terceros mediante OAuth. Para más información, consulte Autorización del acceso a las API REST con OAuth 2.0.

En la sección Build Details (Detalles de la compilación), agregue los detalles de configuración específicos del marco de front-end que prefiera.

  1. Seleccione Next.js en la lista desplegable Valores preestablecidos de compilación.

  2. Conserve el valor predeterminado en el cuadro Ubicación de la aplicación.

  3. Deje en blanco el cuadro Ubicación de la aplicación.

  4. Deje en blanco el cuadro Ubicación del artefacto de la aplicación.

Seleccione Revisar + crear.

Captura de pantalla del botón Crear.

Vista del sitio web

Hay dos aspectos para implementar una aplicación estática. El primero crea los recursos de Azure subyacentes que componen la aplicación. El segundo es un flujo de trabajo que crea y publica la aplicación.

Para poder ir a un nuevo sitio estático, primero la compilación de implementación debe terminar de ejecutarse.

En la ventana Información general de Static Web Apps se muestran una serie de vínculos que le ayudarán a interactuar con la aplicación web.

Captura de pantalla de la ventana de información general de Azure Static Web Apps.

Al seleccionar el banner con el texto, Seleccione esto para comprobar el estado de las ejecuciones de Acciones de GitHub, irá a las Acciones de GitHub en ejecución en su repositorio. Una vez que haya verificado que el trabajo de implementación se haya completado, puede ir a su sitio web a través de la URL generada.

Una vez completado el flujo de trabajo de Acciones de GitHub, puede seleccionar el vínculo con la dirección URL para abrir el sitio web en una pestaña nueva.

Configuración local de un proyecto de Next.js para poder realizar cambios

  1. Clone el nuevo repositorio en la máquina. Asegúrese de reemplazar <YOUR_GITHUB_ACCOUNT_NAME> por el nombre de su cuenta.

    git clone http://github.com/<YOUR_GITHUB_ACCOUNT_NAME>/my-first-static-web-app
    
  2. Abra el proyecto en Visual Studio Code o en el editor de código que prefiera.

Incorporación de datos representados por servidor con un componente del servidor

Para agregar datos representados por servidor en un proyecto de Next.js mediante App Router, edite un componente de Next.js para agregar operaciones del lado servidor para representar datos en el componente. De forma predeterminada, los componentes de Next.js son componentes de servidor que puede representar el servidor.

  1. Abra el archivo app/page.tsx y agregue una operación que establezca el valor de una variable, que se calcula en el lado servidor. Entre los ejemplos se incluyen la captura de datos u otras operaciones que se realizan en el servidor.

    export default function Home() {
        const timeOnServer = new Date().toLocaleTimeString('en-US');
        return(
            ...
        );
    }
    
  2. Importe unstable_noStore desde next/cache y llámelo dentro del componente Home para asegurarse de que la ruta se representa dinámicamente.

    import { unstable_noStore as noStore } from 'next/cache';
    
    export default function Home() {
        noStore();
    
        const timeOnServer = new Date().toLocaleTimeString('en-US');
        return(
            ...
        );
    }
    

    Nota:

    En este ejemplo se fuerza la representación dinámica de este componente para demostrar la representación por parte del servidor de la hora actual del servidor. El modelo App Router de Next.js recomienda almacenar en caché las solicitudes de datos individuales para optimizar el rendimiento de la aplicación de Next.js. Más información sobre la captura y el almacenamiento en caché de datos en Next.js.

  3. Actualice el componente Home en app/pages.tsx para representar los datos del lado servidor.

    import { unstable_noStore as noStore } from 'next/cache';
    
    export default function Home() {
        noStore();
    
        const timeOnServer = new Date().toLocaleTimeString('en-US');
        return(
            <main className="flex min-h-screen flex-col items-center justify-between p-24">
                <div>
                    This is a Next.js application hosted on Azure Static Web Apps with 
                    hybrid rendering. The time on the server is <strong>{timeOnServer}</strong>.
                </div>
            </main>
        );
    }
    

Incorporación de una ruta de API

Además de los componentes del servidor, Next.js proporciona controladores de ruta que puede usar para crear rutas de API a cualquier aplicación de Next.js. Estas API se pueden capturar en Componentes de cliente.

Comience agregando una ruta de API.

  1. Cree un archivo en app/api/currentTime/route.tsx. Este archivo contiene el controlador de ruta del nuevo punto de conexión de la API.

  2. Agregue una función de controlador para devolver los datos de la API.

    import { NextResponse } from 'next/server';
    
    export const dynamic = 'force-dynamic';
    
    export async function GET() { 
        const currentTime = new Date().toLocaleTimeString('en-US');
    
        return NextResponse.json({ 
            message: `Hello from the API! The current time is ${currentTime}.`
        });
    }
    
  3. Cree un archivo en app/components/CurrentTimeFromAPI.tsx. Este componente crea un contenedor para el componente de cliente que captura la API del explorador.

  4. Agregue un componente de cliente que capture la API en este archivo.

    'use client';
    
    import { useEffect, useState } from 'react';
    
    export function CurrentTimeFromAPI(){
        const [apiResponse, setApiResponse] = useState('');
        const [loading, setLoading] = useState(true);
    
        useEffect(() => {
            fetch('/api/currentTime')
                .then((res) => res.json())
                .then((data) => {
                setApiResponse(data.message);
                setLoading(false);
                });
            }, 
        []);
    
        return (
            <div className='pt-4'>
                The message from the API is: <strong>{apiResponse}</strong>
            </div>
        )
    }
    

Este componente captura la API con un useEffect enlace de React que represente el componente una vez completada la carga. La 'use client' directiva identifica este elemento como un componente de cliente. Para más información, consulte Componentes de cliente.

  1. Edite app/page.tsx para importar y representar el CurrentTimeFromAPI componente de cliente.

    import { unstable_noStore as noStore } from 'next/cache';
    import { CurrentTimeFromAPI } from './components/CurrentTimeFromAPI';
    
    export default function Home() {
        noStore();
    
        const timeOnServer = new Date().toLocaleTimeString('en-US');
        return(
            <main className="flex min-h-screen flex-col items-center justify-between p-24">
                <div>
                    This is a Next.js application hosted on Azure Static Web Apps with 
                    hybrid rendering. The time on the server is <strong>{timeOnServer}</strong>.
                </div>
                <CurrentTimeFromAPI />
            </main>
        );
    }
    
  2. El resultado de la ruta de la API se muestra en la página.

Captura de pantalla que muestra la salida de la ruta de API.

Configuración de la versión del runtime de Next.js

Algunas versiones de Next.js requieren versiones específicas de Node.js. Para configurar una versión concreta de Node, puede establecer la propiedad "engines" de package.json archivo para designar una versión.

{
  ...
  "engines": {
    "node": "18.17.1"
  }
}

Establecimiento de variables de entorno para Next.js

Next.js usa variables de entorno tanto en tiempo de compilación como en tiempo de solicitud, para que puedan generarse de páginas de forma estática y dinámica de páginas con representación del lado servidor. Por consiguiente, establezca variables de entorno en las tareas de compilación e implementación, y en las variables de entorno del recurso de Azure Static Web Apps.

...
      - name: Build And Deploy
        id: builddeploy
        uses: Azure/static-web-apps-deploy@v1
        with:
          azure_static_web_apps_api_token: ${{ secrets.AZURE_STATIC_WEB_APPS_API_TOKEN }}
          repo_token: ${{ secrets.GITHUB_TOKEN }} # Used for Github integrations (i.e. PR comments)
          action: "upload"
          app_location: "/" 
          api_location: ""
          output_location: "" 
        env:
          DB_HOST: ${{ secrets.DB_HOST }}
          DB_USER: ${{ secrets.DB_USER }}
          DB_DATABASE: ${{ secrets.DB_DATABASE }}
          DB_PASSWORD: ${{ secrets.DB_PASSWORD }}
          DB_PORT: ${{ secrets.DB_PORT }}
...

Habilitación de la característica independiente

Cuando el tamaño de la aplicación supera los 250 Mb, la característica Seguimiento de archivos de salida de Next.js ayuda a optimizar el tamaño de la aplicación y mejorar el rendimiento.

Esta característica, además, crea una versión comprimida de toda la aplicación con las dependencias de paquetes necesarias integradas en una carpeta denominada .next/standalone. Esta carpeta está pensada para implementarse por sí sola sin dependencias node_modules adicionales.

Para habilitar la característica standalone, agregue la siguiente propiedad adicional a next.config.js:

module.exports ={
    output:"standalone",
}

También deberá configurar el comando build en el archivo package.json para copiar archivos estáticos en la salida independiente.

{
  ...
  "scripts": {
    ...
    "build": "next build && cp -r .next/static .next/standalone/.next/ && cp -r public .next/standalone/"
    ...
  }
  ...
}

Configuración del enrutamiento y el middleware de Next.js para la implementación en Azure Static Web Apps

El proyecto de Next.js se puede configurar para tener un control personalizado de rutas con redirecciones, reescrituras y middleware. Estos controladores se usan normalmente para la autenticación, la personalización, el enrutamiento y la internacionalización. El control personalizado afecta al enrutamiento predeterminado del sitio de Next.js y la configuración debe ser compatible con el hospedaje en Static Web Apps.

Static Web Apps valida que el sitio de Next.js se haya implementado correctamente agregando una página al sitio en tiempo de compilación. La página se denomina public/.swa/health.html y Static Web Apps comprueba el inicio y la implementación correctos del sitio. Para ello, vaya a /.swa/health.html y compruebe una respuesta correcta. El middleware y el enrutamiento personalizado, donde se incluyen redireccionamientos y reescrituras, pueden afectar al acceso de la ruta de acceso de /.swa/health.html, lo que puede impedir la validación de la implementación de Static Web Apps. Para configurar el middleware y el enrutamiento para una implementación correcta en Static Web Apps, siga estos pasos:

  1. Excluya las rutas a partir de .swa en el archivo middleware.ts (o .js) en la configuración de middleware.

    export const config = {
      matcher: [
        /*
         * Match all request paths except for the ones starting with:
         * - .swa (Azure Static Web Apps)
         */
        '/((?!.swa).*)',
      ],
    }
    
  2. Configure las redirecciones en next.config.js para excluir rutas a partir de .swa

    module.exports = {
        async redirects() {
            return [
              {
                source: '/((?!.swa).*)<YOUR MATCHING RULE>',
                destination: '<YOUR REDIRECT RULE>', 
                permanent: false,
              },
            ]
        },
    };
    
  3. Configure las reescrituras en next.config.js para excluir rutas a partir de .swa

    module.exports = {
        async rewrites() {
            return {
                beforeFiles: [
                    {
                        source: '/((?!.swa).*)<YOUR MATCHING RULE>',
                        destination: '<YOUR REWRITE RULE>', 
                    }
                ]
            }
        },
    };
    

Estos fragmentos de código excluyen las rutas de acceso que comiencen por .swa de ser controladas por el middleware o el enrutamiento personalizado. Estas reglas garantizan que las rutas de acceso se resuelvan según lo previsto durante la validación de la implementación.

Habilitación del registro para Next.js

De acuerdo con los procedimientos recomendados para la solución de problemas de la API de servidor de Next.js, agregue el registro a la API para capturar estos errores. El registro en Azure usa Application Insights. Para precargar este SDK, debe crear un script de inicio personalizado. Para obtener más información:

Limpieza de recursos

Si no va a seguir usando esta aplicación, puede eliminar la instancia de Azure Static Web Apps mediante los siguientes pasos:

  1. Abra Azure Portal.
  2. Busque my-first-web-static-app en la barra de búsqueda superior.
  3. Seleccione el nombre de la aplicación.
  4. Seleccione Eliminar.
  5. Seleccione para confirmar la acción de eliminación (esta acción puede tardar unos minutos en completarse).

Pasos siguientes