Fase 0 SPA/SSR: scaffold Next.js 16 (App Router) + Tailwind v4 + home SSR
Inicia la reescritura del frontend a una app Next.js con SSR (Django pasará a ser API JSON). No toca producción: Django sigue sirviendo www; Next corre aparte en :3001. - web-next/: Next.js 16 App Router, TypeScript, Tailwind CSS v4, alias @/*. - lib/api.ts: cliente de la API Django (SSR -> 127.0.0.1:8001; navegador -> /api relativo vía Caddy). - app/page.tsx: home con SSR por petición (force-dynamic) que hace fetch de /api/home/news/ y /api/home/status/ y renderiza noticias + estado con Tailwind. - app/layout.tsx: lang=es + SEO (title/description/keywords/OpenGraph) por el Metadata API de Next (renderizado en servidor). - Servicio systemd novawow-next (next start -p 3001, DJANGO_API_BASE). Nota Next 16 (breaking): params/searchParams son Promise (await); fetch no se cachea por defecto. Verificado: SSR sirve HTML con datos reales de Django y SEO en el <head>; producción Django intacta. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,35 @@
|
||||
// Cliente de la API JSON de Django.
|
||||
// - En SSR (servidor Next) llamamos directo a gunicorn por 127.0.0.1:8001.
|
||||
// - En el navegador usamos rutas relativas (/api/...) que Caddy enruta a Django.
|
||||
const SERVER_BASE = process.env.DJANGO_API_BASE || 'http://127.0.0.1:8001'
|
||||
|
||||
function base(): string {
|
||||
return typeof window === 'undefined' ? SERVER_BASE : ''
|
||||
}
|
||||
|
||||
export async function apiGet<T>(path: string, init?: RequestInit): Promise<T> {
|
||||
const res = await fetch(`${base()}${path}`, {
|
||||
// Datos siempre frescos (SSR por petición); ajústese por endpoint si procede.
|
||||
cache: 'no-store',
|
||||
headers: { Accept: 'application/json' },
|
||||
...init,
|
||||
})
|
||||
if (!res.ok) throw new Error(`API ${path} -> HTTP ${res.status}`)
|
||||
return res.json() as Promise<T>
|
||||
}
|
||||
|
||||
export interface Noticia {
|
||||
id: number
|
||||
titulo: string
|
||||
fecha: string | null
|
||||
contenido: string
|
||||
enlace: string | null
|
||||
}
|
||||
|
||||
export interface ServerStatus {
|
||||
server_name: string | null
|
||||
address: string | null
|
||||
expansion: string
|
||||
online_characters: number
|
||||
status: 'Online' | 'Offline'
|
||||
}
|
||||
Reference in New Issue
Block a user