1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
|
// SPDX-FileCopyrightText: 2026 Progmasoft <support@progmasoft.com>
// SPDX-License-Identifier: AGPL-3.0-or-later WITH AdditionRef-Progmasoft-Patent-Grant-1.1
import type { Metadata } from "next";
import { headers } from "next/headers";
import type { ReactNode } from "react";
import { nonceHeader } from "@/lib/content-security-policy";
import { getLocale } from "@/lib/locale.server";
import { textDirection } from "@/lib/localization";
import "./globals.css";
import "./viget.css";
// Apply the stored theme before the body is painted. PreferenceControls keeps
// this value synchronized after hydration, while this small bootstrap prevents
// a light flash on every route—including dashboard loading and error states.
const themeBootstrap = `
(() => {
try {
const theme = localStorage.getItem("progmasoft_theme") === "dark" ? "dark" : "light";
document.documentElement.dataset.theme = theme;
document.documentElement.style.colorScheme = theme;
} catch {}
})();
`;
export const metadata: Metadata = {
// The apex host is the only public organization canonical. The www host is a
// transport-level redirect and account pages opt out of indexing below.
metadataBase: new URL("https://progmasoft.com"),
title: {
default: "Progmasoft",
template: "%s · Progmasoft",
},
description:
"Progmasoft builds programming-language, package-management, and developer-tooling systems.",
applicationName: "Progmasoft",
robots: {
index: true,
follow: true,
},
};
export default async function RootLayout({
children,
}: Readonly<{ children: ReactNode }>) {
const locale = await getLocale();
// The proxy gives each page a nonce; its policy admits no other inline script.
const nonce = (await headers()).get(nonceHeader) ?? undefined;
return (
<html
lang={locale}
data-text-direction={textDirection(locale)}
// data-theme belongs to the bootstrap script and the theme control only.
// Rendered here, React would set it back to light whenever the server
// re-renders the layout (a language switch), and the page would flash.
suppressHydrationWarning
>
<head>
<script
nonce={nonce}
dangerouslySetInnerHTML={{ __html: themeBootstrap }}
/>
</head>
<body>{children}</body>
</html>
);
}
|