Files
NightSpire/web-next/app/[locale]/layout.tsx
T
Inna 97ccb8a179 El CSS del tema entra por el build en vez de un <link> desde public/
Antes: <link href="/ns-themes/.../nightspire-style.css?v=2"> en el <head>. Una
peticion aparte, sin minificar y con cache invalidada a mano con ?v=2.

Ahora: app/theme.css, importado al FINAL de globals.css. Next lo compila,
minifica y le pone hash de contenido; se sirve con cache immutable y hay una
hoja de estilo menos (4 -> 3).

⚠ El @import va el ULTIMO y no es cosmético: el tema se diseñó contra los
defaults del navegador y el preflight de Tailwind los pisa (box-sizing,
alturas). Antes ganaba la cascada por cargarse el último en el <head>; ahora
gana por ser el último import. Si sube de sitio, el diseño se rompe.

Las url() pasan a ABSOLUTAS (/ns-themes/ns-ryu/...). Los assets siguen en
public/, y así el compilador no intenta resolverlos: el @font-face declara
.eot/.otf/.ttf que NO existen (solo hay .woff) y con rutas relativas el build
fallaría.

Verificado: los 6 páginas dan exactamente el mismo alto que antes (8159, 1356,
2645, 1356, 2221, 2349 px) con la misma fuente y colores, y el input del login
sigue en box-sizing:content-box — que es justo donde el preflight rompía. Ojo:
el md5 de las capturas NO sirve para comparar, porque la cabecera lleva un vídeo
y cada captura pilla un fotograma distinto.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-15 16:20:06 +00:00

103 lines
4.0 KiB
TypeScript

import type { Metadata } from 'next'
import Script from 'next/script'
import { notFound } from 'next/navigation'
import { NextIntlClientProvider, hasLocale } from 'next-intl'
import { getTranslations, setRequestLocale } from 'next-intl/server'
import { routing } from '@/i18n/routing'
import { Header } from '@/components/Header'
import { Video } from '@/components/Video'
import { Social } from '@/components/Social'
import { Footer } from '@/components/Footer'
import { CookieBanner } from '@/components/CookieConsent'
import '../globals.css'
export function generateStaticParams() {
return routing.locales.map((locale) => ({ locale }))
}
// SEO por idioma (SSR) vía Metadata API.
export async function generateMetadata({
params,
}: {
params: Promise<{ locale: string }>
}): Promise<Metadata> {
const { locale } = await params
const t = await getTranslations({ locale, namespace: 'Metadata' })
return {
title: t('title'),
description: t('description'),
openGraph: {
siteName: 'NightSpire',
title: t('title'),
description: t('description'),
type: 'website',
locale: locale === 'es' ? 'es_ES' : 'en_US',
url: 'https://www.nightspire.gg/',
},
}
}
export default async function LocaleLayout({
children,
params,
}: {
children: React.ReactNode
params: Promise<{ locale: string }>
}) {
const { locale } = await params
if (!hasLocale(routing.locales, locale)) notFound()
setRequestLocale(locale)
return (
<html lang={locale}>
<head>
{/* Iconos del sitio (idénticos a la web Django) */}
<link rel="apple-touch-icon" sizes="180x180" href="/apple-touch-icon.png" />
<link rel="icon" type="image/png" sizes="32x32" href="/favicon-32x32.png" />
<link rel="icon" type="image/png" sizes="194x194" href="/favicon-194x194.png" />
<link rel="icon" type="image/png" sizes="192x192" href="/android-chrome-192x192.png" />
<link rel="icon" type="image/png" sizes="16x16" href="/favicon-16x16.png" />
<link rel="manifest" href="/site.webmanifest" />
<link rel="mask-icon" href="/safari-pinned-tab.svg" color="#47210a" />
<link rel="shortcut icon" href="/favicon.ico" />
{/* Font Awesome (mismos iconos que la web Django) */}
<link
rel="stylesheet"
href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.6.0/css/all.min.css"
/>
{/* Config de los tooltips de wowhead (debe definirse antes de tooltips.js).
OJO con el `window.`: tooltips.js lee `window.whTooltips`, y un `const` a
nivel de script queda en el ámbito léxico del script (no crea propiedad en
window), así que la config se ignoraba entera y valían los valores por
defecto de wowhead.
`colorLinks` tiñe cada enlace según la calidad del ítem e `iconizeLinks` le
antepone el icono pequeño: los dos replican lo que hace el store original
(sus enlaces acaban con las clases `icontinyl q4`). Sin colorLinks los
nombres caen al `a{color:#2471a9}` del tema y salen todos azules.
`renameLinks` NO: el texto de los enlaces es el nombre de nuestra BD (en
español), y wowhead lo sobreescribiría. El idioma del tooltip lo da el
subdominio del enlace (es./www.). */}
<script
dangerouslySetInnerHTML={{
__html: 'window.whTooltips={colorLinks:true,iconizeLinks:true,renameLinks:false};',
}}
/>
</head>
<body>
<NextIntlClientProvider>
<Header />
<Video />
{children}
<Social />
<Footer />
<CookieBanner />
</NextIntlClientProvider>
{/* Tooltips de wowhead (WotLK) en todos los enlaces .../wowhead.com/... y
elementos con data-wowhead. Funciona con contenido añadido por React
(carrito, búsquedas) porque delega el hover en el documento. */}
<Script src="https://wow.zamimg.com/js/tooltips.js" strategy="afterInteractive" />
</body>
</html>
)
}