agency-web/app/layout.tsx

119 lines
3.5 KiB
TypeScript

import type { Metadata } from "next";
import "./globals.css";
import SmoothScroll from "./components/SmoothScroll";
import Cursor from "./components/Cursor";
import { SITE, services, faqs } from "./content";
export const metadata: Metadata = {
title: "Results-driven digital marketing agency | Feedback Studios",
description: SITE.description,
// Test environment — keep everything out of search engines.
// Remove these robots directives (here + app/robots.ts + next.config.mjs
// X-Robots-Tag header) to flip the site to index when it goes live.
robots: {
index: false,
follow: false,
nocache: true,
googleBot: { index: false, follow: false },
},
};
/* JSON-LD: Organization + WebSite (+SearchAction) + Service (per core
service) + FAQPage. Structure is launch-ready; the page stays noindex
in this test env via the robots directives above. */
function StructuredData() {
const graph = [
{
"@type": "Organization",
"@id": `${SITE.url}/#organization`,
name: SITE.name,
url: SITE.url,
description: SITE.description,
email: SITE.email,
slogan: SITE.tagline,
knowsAbout: [
"digital marketing",
"search engine optimization",
"paid advertising",
"content marketing",
"social media marketing",
"conversion rate optimization",
],
},
{
"@type": "WebSite",
"@id": `${SITE.url}/#website`,
url: SITE.url,
name: SITE.name,
publisher: { "@id": `${SITE.url}/#organization` },
potentialAction: {
"@type": "SearchAction",
target: {
"@type": "EntryPoint",
urlTemplate: `${SITE.url}/?s={search_term_string}`,
},
"query-input": "required name=search_term_string",
},
},
...services.map((s) => ({
"@type": "Service",
name: s.name,
description: s.desc,
serviceType: s.name,
provider: { "@id": `${SITE.url}/#organization` },
areaServed: "Worldwide",
})),
{
"@type": "FAQPage",
"@id": `${SITE.url}/#faq`,
mainEntity: faqs.map((f) => ({
"@type": "Question",
name: f.q,
acceptedAnswer: { "@type": "Answer", text: f.a },
})),
},
];
return (
<script
type="application/ld+json"
dangerouslySetInnerHTML={{
__html: JSON.stringify({ "@context": "https://schema.org", "@graph": graph }),
}}
/>
);
}
export default function RootLayout({
children,
}: {
children: React.ReactNode;
}) {
return (
<html lang="en">
<head>
{/* Satoshi (workhorse sans) + Newsreader (editorial display, in
globals via @import) + Spline Sans Mono (data/labels). */}
<link rel="preconnect" href="https://api.fontshare.com" crossOrigin="" />
<link
rel="stylesheet"
href="https://api.fontshare.com/v2/css?f[]=satoshi@300,400,500,700,900&display=swap"
/>
<link rel="preconnect" href="https://fonts.googleapis.com" />
<link rel="preconnect" href="https://fonts.gstatic.com" crossOrigin="" />
<meta name="robots" content="noindex, nofollow, noarchive, nosnippet" />
<meta name="theme-color" content="#07070b" />
</head>
<body>
<StructuredData />
<a href="#main" className="skip-link">
Skip to content
</a>
<div className="grain" aria-hidden="true" />
<SmoothScroll />
<Cursor />
{children}
</body>
</html>
);
}