Files
portifolio-evandrodevbr/app/layout.tsx
T

168 lines
4.7 KiB
TypeScript

import type { Metadata, Viewport } from "next";
import { Geist_Mono, Space_Grotesk } from "next/font/google";
import localFont from "next/font/local";
import type { ReactNode } from "react";
import { safeJsonLd } from "@/lib/jsonld";
import { buildPersonJsonLd, buildWebSiteJsonLd } from "@/lib/seo";
import { siteUrl } from "@/lib/site-content";
import CinematicOverlays from "./components/cinematic/CinematicOverlays";
import GoogleAnalytics from "./components/GoogleAnalytics";
import { Header } from "./components/Header";
import "./globals.css";
const defaultTitle = "Sistemas sob medida para empresas | Evandro.dev.br";
const seoDescription =
"Desenvolvimento de sistemas web, aplicativos e integrações sob medida. Do entendimento do negócio à entrega em produção, com Evandro Fonseca Junior. Base em Santa Catarina e atendimento remoto.";
const spaceGrotesk = Space_Grotesk({
subsets: ["latin"],
weight: ["400", "500", "600", "700"],
display: "swap",
variable: "--font-space-grotesk",
});
const geistMono = Geist_Mono({
subsets: ["latin"],
weight: ["400", "500", "600"],
display: "swap",
variable: "--font-geist-mono",
});
const monumentExtended = localFont({
src: [
{
path: "../public/fonts/MonumentExtended-Regular.otf",
weight: "400",
style: "normal",
},
{
path: "../public/fonts/MonumentExtended-Ultrabold.otf",
weight: "800",
style: "normal",
},
],
display: "swap",
variable: "--font-monument-extended",
});
export const metadata: Metadata = {
title: {
default: defaultTitle,
template: "%s | Evandro Fonseca Junior",
},
description: seoDescription,
authors: [{ name: "Evandro Fonseca Junior" }],
creator: "Evandro Fonseca Junior",
publisher: "Evandro Fonseca Junior",
applicationName: "Evandro.dev.br",
category: "Technology",
metadataBase: new URL(siteUrl),
alternates: {
canonical: "/",
},
formatDetection: {
email: false,
address: false,
telephone: false,
},
openGraph: {
title: defaultTitle,
description: seoDescription,
url: siteUrl,
siteName: "Evandro.dev.br",
locale: "pt_BR",
type: "website",
images: [
{
url: "/opengraph-image",
width: 1200,
height: 630,
alt: "Evandro.dev.br | Sistemas sob medida para empresas",
},
],
},
twitter: {
card: "summary_large_image",
title: defaultTitle,
description: seoDescription,
creator: "@evandrodevbr",
images: [
{
url: "/opengraph-image",
alt: "Evandro.dev.br | Sistemas sob medida para empresas",
},
],
},
robots: {
index: true,
follow: true,
googleBot: {
index: true,
follow: true,
"max-video-preview": -1,
"max-image-preview": "large",
"max-snippet": -1,
},
},
};
export const viewport: Viewport = {
themeColor: "#000000",
width: "device-width",
initialScale: 1,
maximumScale: 5,
};
interface RootLayoutProps {
children: ReactNode;
}
export default function RootLayout({ children }: Readonly<RootLayoutProps>) {
const jsonLd = {
"@context": "https://schema.org",
"@graph": [buildWebSiteJsonLd(), buildPersonJsonLd()],
};
return (
<html
lang="pt-BR"
className={`${spaceGrotesk.variable} ${geistMono.variable} ${monumentExtended.variable}`}
>
<head>
{/* Set arrival policy before native restoration and client-side layout changes. */}
<style id="arrival-scroll-policy">{`html { scroll-behavior: auto !important; }`}</style>
<script>{`
addEventListener("load", () => {
const sheet = document.getElementById("arrival-scroll-policy")?.sheet;
if (sheet) sheet.disabled = true;
}, { once: true });
if (location.pathname === "/") {
const navigation = performance.getEntriesByType("navigation")[0];
if (navigation?.type !== "back_forward") {
history.scrollRestoration = "manual";
if (navigation?.type === "reload" && location.hash) {
history.replaceState(history.state, "", location.pathname + location.search);
}
addEventListener("pagehide", () => {
history.scrollRestoration = "auto";
}, { once: true });
}
}
`}</script>
</head>
<body>
<script type="application/ld+json">{safeJsonLd(jsonLd)}</script>
<a className="skip-link" href="#main-content">
Pular para o conteúdo
</a>
<Header />
<CinematicOverlays />
<div id="main-content" tabIndex={-1}>
{children}
</div>
<GoogleAnalytics />
</body>
</html>
);
}