This repository has been archived on 2026-05-03. You can view files and clone it. You cannot open issues or pull requests or push a commit.
Files
Kismet Hasanaj 34dc9aec52 .
2026-05-02 20:07:02 +02:00

163 lines
5.3 KiB
TypeScript
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
/**
* layout.tsx — Root layout for Novarix Networks
*
* Responsible for:
* • Loading "DM Sans" via next/font/google (self-hosted, zero CLS).
* • Applying global CSS (globals.css).
* • Exporting page-level metadata for <head> injection, Open Graph, and
* Twitter card meta.
* • Setting viewport and theme-colour meta tags.
* • Injecting JSON-LD Organisation structured data for rich search results.
*
* ─── Adding pages ────────────────────────────────────────────────────────
*
* New pages created under /app inherit this layout automatically.
* To create a nested layout (e.g. for a /services sub-section), add a
* layout.tsx inside /app/services/ — Next.js will compose them.
*/
import type { Metadata, Viewport } from "next";
import { DM_Sans } from "next/font/google";
import "./globals.css";
/* ── Font ──────────────────────────────────────────────────────────────── */
/**
* DM Sans loaded via next/font/google.
* The font is downloaded at build time and served from /_next/static/media/
* — no third-party request at runtime, eliminating the CLS caused by
* loading from fonts.googleapis.com.
*
* `variable` exposes the font as a CSS custom property (--font-dm-sans)
* so globals.css can reference it without importing from JS.
*/
const dmSans = DM_Sans({
subsets: ["latin"],
variable: "--font-dm-sans",
display: "swap",
});
/* ── JSON-LD structured data ───────────────────────────────────────────── */
const jsonLd = {
"@context": "https://schema.org",
"@type": "Organization",
name: "Novarix Networks",
url: "https://novarixnet.com",
email: "contact@novarixnet.com",
description:
"Novarix Networks provides business connectivity, managed network services, and transit-focused infrastructure support for organisations that need dependable engineering and clear technical ownership.",
knowsAbout: [
"Business Connectivity",
"Managed Network Services",
"IP Transit",
"Peering",
"BGP",
"Network Engineering",
],
};
/* ── Site metadata ─────────────────────────────────────────────────────── */
export const metadata: Metadata = {
/**
* metadataBase resolves relative URLs in metadata fields (e.g. OG images).
* Pull from an environment variable per-environment if needed:
*
* metadataBase: new URL(process.env.NEXT_PUBLIC_SITE_URL ?? "https://novarixnet.com"),
*/
metadataBase: new URL("https://novarixnet.com"),
title: {
default: "Novarix Networks",
template: "%s | Novarix Networks",
},
description:
"Novarix Networks provides business connectivity, managed network services, and transit-focused infrastructure support for organisations that need dependable engineering and clear technical ownership.",
applicationName: "Novarix Networks",
keywords: [
"Novarix Networks",
"ISP",
"Managed Service Provider",
"MSP",
"IP Transit",
"Business Connectivity",
"Peering",
"BGP",
"IXP",
"CDN Edge",
"Network Engineering",
],
authors: [{ name: "Novarix Networks" }],
creator: "Novarix Networks",
publisher: "Novarix Networks",
alternates: {
canonical: "/",
},
openGraph: {
type: "website",
url: "https://novarixnet.com",
siteName: "Novarix Networks",
title: "Novarix Networks",
description:
"Business connectivity, managed network services, transit, and engineering-led infrastructure support.",
locale: "en_GB",
/*
* Add a 1200 × 630 px image to /public/og-image.png to enable rich
* link previews on LinkedIn, Slack, and Facebook:
*
* images: [{ url: "/og-image.png", width: 1200, height: 630 }],
*/
},
twitter: {
card: "summary_large_image",
title: "Novarix Networks",
description:
"Business connectivity, managed network services, transit, and engineering-led infrastructure support.",
/*
* images: ["/og-image.png"],
*/
},
robots: {
index: true,
follow: true,
},
};
/* ── Viewport & theme colour ───────────────────────────────────────────── */
export const viewport: Viewport = {
width: "device-width",
initialScale: 1,
themeColor: [
{ media: "(prefers-color-scheme: light)", color: "#ffffff" },
{ media: "(prefers-color-scheme: dark)", color: "#020617" },
],
};
/* ── Root layout component ─────────────────────────────────────────────── */
export default function RootLayout({
children,
}: Readonly<{ children: React.ReactNode }>) {
return (
<html lang="en-GB" suppressHydrationWarning className={dmSans.variable}>
<head>
<script
type="application/ld+json"
dangerouslySetInnerHTML={{ __html: JSON.stringify(jsonLd) }}
/>
</head>
<body>{children}</body>
</html>
);
}