ToolActToolAct

Demo

Página de demostración

DatosSSR
rettrue
msgnull
statusCode0
dataHello World

¿Qué es SSR?

Esta página demo no es una utilidad final para usuarios, sino una pequeña ruta de referencia para renderizado del lado del servidor. Muestra cómo una página de Next.js App Router puede obtener datos en el servidor, insertar el resultado en el primer HTML y cargar las traducciones del locale actual. Por eso sirve para comprobar infraestructura compartida: variables de entorno, peticiones firmadas del servidor, forma de la respuesta API, enrutamiento por locale y carga de traducciones. Si esta página funciona, el camino básico de SSR está sano antes de depurar una herramienta más compleja. Si falla, el problema probablemente está en la configuración común del servidor o en la conectividad con la API. Debe mantenerse simple para seguir siendo una prueba rápida tras despliegues o cambios de framework.

Cómo usar

Cómo usar

  1. La página llama automáticamente a la API del backend
  2. El HTML incluye contenido pre-renderizado, sin necesidad de solicitud del cliente
  3. Consulta los datos devueltos por la API
  4. Ideal para páginas que necesitan optimización SEO

Notas de desarrollo

  • Usa esta página como prueba de humo para SSR, carga de localización, solicitudes firmadas al servidor y conectividad con la API.
  • Si esta página falla, revisa la configuración compartida del servidor antes de depurar una página de herramienta específica.

Casos de uso

Verificar la ruta de API firmada del lado del servidorAbre la página demo para confirmar que los datos SSR pueden obtenerse a través de serverPageFetch con la configuración actual de locale y API_BASE_URL. La página es forzadamente dinámica, así que los campos renderizados ret, msg, statusCode y data siempre reflejan la respuesta más reciente del servidor, que es lo que se necesita para una prueba de humo. Este es un harness de depuración, no una función de usuario: una respuesta sana en esta ruta significa que la clave de firma compartida, el almacén de nonces y la negociación de locale están en buen estado antes de depurar una herramienta real.
Comprobar cómo los campos de respuesta del backend se renderizan en el shell de la appLa página muestra ret, msg, statusCode y data con una insignia SSR, lo que da a los desarrolladores una prueba de humo compacta para la forma de la respuesta y la presentación del estado de error. Como la página se renderiza en el servidor, puedes confirmar que la carga de mensajes i18n, el segmento de locale y el wrapper de firma funcionan sin instrumentar manualmente el cliente. Comparar el código ret y el título de error renderizado lado a lado también ayuda a verificar que el mapeo de errores está conectado correctamente, así que una página real mostrará errores traducidos en lugar de cadenas crudas de la API.
Usarla como referencia interna de integraciónAl ser forzadamente dinámica y renderizada en el servidor, esta página es un ejemplo compacto para futuras herramientas que necesiten acceso firmado a la API del servidor en lugar de procesamiento puramente del lado del cliente. Úsala como referencia funcional al añadir otra página SSR que llame al backend. Mantén el área superficial de la demo a propósito mínima: una forma de respuesta pequeña y predecible es lo que hace fiable la prueba de humo, mientras que una demo extensa oscurecería qué subsistema se rompió realmente.
Detectar regresiones de enrutamiento de locale con esta verificación SSRVisita la demo bajo varios prefijos de locale para confirmar que las etiquetas localizadas y los campos ret/msg/data siguen renderizándose del lado del servidor, exponiendo problemas de enrutamiento o del cargador de traducciones a tiempo. Una clave de traducción faltante o un segmento desplazado bajo un locale suele aparecer aquí antes de que se pruebe cualquier herramienta visible para el usuario. Cuando la demo falla bajo un locale pero pasa bajo otro, la regresión está casi siempre en el segmento de locale, el cargador de mensajes o el árbol de enrutamiento, no en el wrapper de firma.
Verificar las cabeceras X-Timestamp, X-Nonce y X-Sign en el registro de redInspecciona la solicitud saliente de la página demo para confirmar que la petición firmada del servidor incluye las cabeceras esperadas, que es la forma más rápida de depurar errores 401/403 de la API real. Las mismas cabeceras también aparecen en las herramientas de desarrollo del navegador al hacer proxy a través del servidor de desarrollo local, así que el wrapper de firma puede verificarse de extremo a extremo. Si la firma parece correcta pero el servidor upstream sigue rechazando, la desviación del reloj en el servidor (X-Timestamp) o una colisión de nonce (X-Nonce) suelen ser la causa, y el registro de solicitudes de la demo es el lugar más limpio para confirmar ambos antes de abrir un ticket en el backend.

Principio técnico

Esta página Demo está construida sobre Next.js 16 App Router y usa renderizado del lado del servidor (SSR) por defecto. Cuando un usuario solicita la página, el servidor Node.js primero ejecuta el componente React, llama a la API del backend para obtener datos y devuelve el HTML completamente renderizado al navegador en una única respuesta. El navegador comienza a analizar y pintar el HTML de inmediato, por lo que los usuarios ven el contenido completo en el primer fotograma sin esperar a que el JavaScript se descargue y ejecute. Esto contrasta fuertemente con el renderizado del lado del cliente (CSR) tradicional. Con CSR, el servidor solo devuelve un shell HTML casi vacío y un enlace a JS; el navegador tiene que descargar el paquete JS, ejecutar la inicialización del framework, llamar a las APIs para obtener datos y solo entonces renderizar la página. Desde la perspectiva del usuario es 'una pantalla en blanco durante un rato', y es aún peor para los rastreadores de buscadores: la mayoría no ejecutan JavaScript y solo ven el shell vacío. Tras el SSR, Next.js también inyecta un fragmento de JavaScript para realizar la 'hidratación': asociar el DOM existente con el árbol de componentes React y vincular los listeners de eventos para que la página se vuelva interactiva. El flujo completo es: análisis HTML -> carga CSS -> descarga JS -> hidratación -> página interactiva. Entre las tres Core Web Vitals, LCP (Largest Contentful Paint) y CLS (Cumulative Layout Shift) suelen ser mejores con SSR, mientras que INP (Interaction to Next Paint) depende de la velocidad de hidratación y la calidad de implementación de los manejadores de eventos.

  • Next.js App Router: las páginas del App Router son Server Components por defecto, se ejecutan en el servidor y devuelven HTML automáticamente sin configuración adicional.
  • SSR vs CSR: SSR ofrece un primer pintado rápido y compatibilidad con SEO a costa de recursos del servidor; CSR se adapta a paneles internos y otros escenarios interactivos que no necesitan SEO.
  • Flujo del primer pintado: análisis HTML -> carga y renderizado CSS -> descarga y ejecución JS -> hidratación React -> página interactiva; cada paso afecta al LCP.
  • Compatibilidad con rastreo SEO: los rastreadores principales como Googlebot y Bingbot leen el texto HTML directamente; la salida SSR con contenido completo garantiza cobertura de rastreo.
  • Umbrales de Web Vitals: LCP < 2,5 s, INP < 200 ms, CLS < 0,1 son los umbrales recomendados como 'buenos' por Google; SSR facilita alcanzar LCP y CLS.
  • Solicitudes firmadas: la página Demo llama a la API del backend a través de serverApiFetch en el servidor, portando automáticamente X-Timestamp, X-Nonce y X-Sign para completar la autenticación.

Ejemplos

SSR (renderizado del lado del servidor)

// app/page.tsx (Server Component por defecto)
export default async function Page() {
  const data = await fetch('/api/info').then(r => r.json());
  return <div>{data.title}</div>;
}
// El HTML ya contiene directamente <div>contenido real</div>

CSR (renderizado del lado del cliente)

'use client';
import { useEffect, useState } from 'react';

export default function Page() {
  const [data, setData] = useState(null);
  useEffect(() => {
    fetch('/api/info').then(r => r.json()).then(setData);
  }, []);
  return <div>{data?.title || 'Loading...'}</div>;
}
// El HTML del primer pintado solo contiene <div>Loading...</div>

Comparación de velocidad del primer pintado

# SSR
FCP: 0.4s  LCP: 0.8s  TTI: 1.2s
SEO: los rastreadores obtienen el contenido completo directamente

# CSR
FCP: 0.6s  LCP: 1.8s  TTI: 2.4s
SEO: los rastreadores deben ejecutar JS para obtener el contenido

Preguntas frecuentes

¿Qué demuestra realmente esta página de demostración?

Es una ruta de referencia con renderizado en servidor (SSR) que muestra cómo una página del App Router de Next.js puede obtener datos en el servidor, incrustarlos en la primera respuesta HTML y, aun así, cargar los textos localizados correctos. No es una utilidad para usuarios finales: es una prueba de humo para desarrolladores.

¿Los datos se obtienen en el servidor o en el navegador?

En el servidor. La página llama a serverApiFetch (con las cabeceras firmadas de src/lib/sign.ts) dentro del React Server Component, así que el navegador recibe un HTML que ya contiene los datos. No hay fetch desde el cliente en la primera carga.

¿Por qué la página muestra a veces datos obsoletos?

Next.js puede cachear la respuesta SSR según la configuración de revalidate. Si necesitas datos frescos en cada solicitud, indica 'export const dynamic = "force-dynamic"' o pasa {cache: 'no-store'} al fetch. La ruta de demo usa el comportamiento por defecto para mantener el ejemplo simple.

¿Puedo copiar este patrón para mi propia página?

Sí, esa es la idea. La ruta muestra cómo combinar getTranslations de next-intl con un fetch en el servidor y pasar el resultado a un Client Component para la interactividad. Copia layout.tsx y page.tsx y sustituye la fuente de datos.

¿Por qué necesito firmar las solicitudes para una API interna?

X-Timestamp / X-Nonce / X-Sign bloquean ataques de replay y aseguran que las solicitudes que llegan desde la web pública provengan realmente de un cliente confiable. La clave de firma es por sesión para usuarios autenticados y un valor por defecto en el resto de casos; consulta src/lib/sign.ts y src/lib/fetch.ts para la implementación.

¿Esta página existirá en las builds de producción?

Forma parte de la app desplegada como referencia, pero no está enlazada desde la página de inicio ni desde la lista de herramientas, ni se anuncia como herramienta de cara al usuario. Tómala como documentación para desarrolladores renderizada en forma de ruta.

¿Qué debería revisar si quiero entender la estructura del proyecto?

Empieza por el layout.tsx y el page.tsx de esta página y luego lee src/i18n.ts (configuración de idiomas), src/i18n/request.ts (carga global de traducciones), src/lib/load-page-messages.ts (traducciones por página) y src/lib/fetch.ts (envoltorios de solicitudes firmadas).