pounce/frontend/src/app/layout.tsx
yves.gugger f7e4c8e6a4
Some checks failed
CI / Frontend Lint & Type Check (push) Has been cancelled
CI / Frontend Build (push) Has been cancelled
CI / Backend Lint (push) Has been cancelled
CI / Backend Tests (push) Has been cancelled
CI / Docker Build (push) Has been cancelled
CI / Security Scan (push) Has been cancelled
Deploy / Build & Push Images (push) Has been cancelled
Deploy / Deploy to Server (push) Has been cancelled
Deploy / Notify (push) Has been cancelled
Update pricing: buttons aligned, competitive pricing (/), USD currency
2025-12-09 17:35:59 +01:00

204 lines
7.4 KiB
TypeScript

import type { Metadata, Viewport } from 'next'
import { Inter, JetBrains_Mono, Playfair_Display } from 'next/font/google'
import './globals.css'
const inter = Inter({
subsets: ['latin'],
variable: '--font-sans',
})
const jetbrainsMono = JetBrains_Mono({
subsets: ['latin'],
variable: '--font-mono',
})
const playfair = Playfair_Display({
subsets: ['latin'],
variable: '--font-display',
})
const siteUrl = process.env.NEXT_PUBLIC_SITE_URL || 'https://pounce.ch'
export const metadata: Metadata = {
metadataBase: new URL(siteUrl),
title: {
default: 'pounce — Domain Intelligence Platform',
template: '%s | pounce',
},
description: 'Professional domain intelligence platform. Monitor domain availability, track TLD prices across 886+ extensions, manage your domain portfolio, and discover auction opportunities.',
keywords: [
'domain monitoring',
'domain availability',
'TLD pricing',
'domain portfolio',
'domain valuation',
'domain auctions',
'domain intelligence',
'domain tracking',
'expiring domains',
'domain name search',
'registrar comparison',
'domain investment',
],
authors: [{ name: 'pounce', url: siteUrl }],
creator: 'pounce',
publisher: 'pounce',
formatDetection: {
email: false,
address: false,
telephone: false,
},
openGraph: {
type: 'website',
locale: 'en_US',
url: siteUrl,
siteName: 'pounce',
title: 'pounce — Domain Intelligence Platform',
description: 'Monitor domain availability, track TLD prices, manage your portfolio, and discover auction opportunities.',
images: [
{
url: `${siteUrl}/og-image.png`,
width: 1200,
height: 630,
alt: 'pounce - Domain Intelligence Platform',
},
],
},
twitter: {
card: 'summary_large_image',
title: 'pounce — Domain Intelligence Platform',
description: 'Monitor domain availability, track TLD prices, manage your portfolio.',
creator: '@pounce_domains',
images: [`${siteUrl}/og-image.png`],
},
robots: {
index: true,
follow: true,
googleBot: {
index: true,
follow: true,
'max-video-preview': -1,
'max-image-preview': 'large',
'max-snippet': -1,
},
},
icons: {
icon: [
{ url: '/favicon.ico', sizes: '32x32' },
{ url: '/favicon-16x16.png', sizes: '16x16', type: 'image/png' },
{ url: '/favicon-32x32.png', sizes: '32x32', type: 'image/png' },
],
shortcut: '/favicon.ico',
apple: '/apple-touch-icon.png',
},
manifest: '/site.webmanifest',
alternates: {
canonical: siteUrl,
},
}
export const viewport: Viewport = {
themeColor: '#00d4aa',
width: 'device-width',
initialScale: 1,
maximumScale: 5,
}
// JSON-LD Structured Data
const jsonLd = {
'@context': 'https://schema.org',
'@graph': [
{
'@type': 'WebSite',
'@id': `${siteUrl}/#website`,
url: siteUrl,
name: 'pounce',
description: 'Professional domain intelligence platform',
publisher: { '@id': `${siteUrl}/#organization` },
potentialAction: {
'@type': 'SearchAction',
target: {
'@type': 'EntryPoint',
urlTemplate: `${siteUrl}/tld-pricing?search={search_term_string}`,
},
'query-input': 'required name=search_term_string',
},
},
{
'@type': 'Organization',
'@id': `${siteUrl}/#organization`,
name: 'pounce',
url: siteUrl,
logo: {
'@type': 'ImageObject',
url: `${siteUrl}/pounce-logo.png`,
width: 512,
height: 512,
},
description: 'Professional domain intelligence platform. Monitor availability, track prices, manage portfolios.',
foundingDate: '2024',
sameAs: ['https://twitter.com/pounce_domains'],
},
{
'@type': 'WebApplication',
'@id': `${siteUrl}/#app`,
name: 'pounce',
url: siteUrl,
applicationCategory: 'BusinessApplication',
operatingSystem: 'Web Browser',
offers: {
'@type': 'AggregateOffer',
lowPrice: '0',
highPrice: '49',
priceCurrency: 'USD',
offerCount: '3',
},
featureList: [
'Domain availability monitoring',
'TLD price comparison (886+ TLDs)',
'Domain portfolio management',
'Algorithmic domain valuation',
'Auction aggregation (Smart Pounce)',
'Email notifications',
'Price alerts',
],
},
],
}
export default function RootLayout({
children,
}: {
children: React.ReactNode
}) {
return (
<html lang="en" className={`${inter.variable} ${jetbrainsMono.variable} ${playfair.variable}`}>
<head>
<script
type="application/ld+json"
dangerouslySetInnerHTML={{ __html: JSON.stringify(jsonLd) }}
/>
<link rel="preconnect" href="https://fonts.googleapis.com" />
<link rel="preconnect" href="https://fonts.gstatic.com" crossOrigin="anonymous" />
{/* PostHog Analytics */}
<script
dangerouslySetInnerHTML={{
__html: `
!function(t,e){var o,n,p,r;e.__SV||(window.posthog && window.posthog.__loaded)||(window.posthog=e,e._i=[],e.init=function(i,s,a){function g(t,e){var o=e.split(".");2==o.length&&(t=t[o[0]],e=o[1]),t[e]=function(){t.push([e].concat(Array.prototype.slice.call(arguments,0)))}}(p=t.createElement("script")).type="text/javascript",p.crossOrigin="anonymous",p.async=!0,p.src=s.api_host.replace(".i.posthog.com","-assets.i.posthog.com")+"/static/array.js",(r=t.getElementsByTagName("script")[0]).parentNode.insertBefore(p,r);var u=e;for(void 0!==a?u=e[a]=[]:a="posthog",u.people=u.people||[],u.toString=function(t){var e="posthog";return"posthog"!==a&&(e+="."+a),t||(e+=" (stub)"),e},u.people.toString=function(){return u.toString(1)+".people (stub)"},o="init Dr Ur fi Lr zr ci Or jr capture Ai calculateEventProperties qr register register_once register_for_session unregister unregister_for_session Jr getFeatureFlag getFeatureFlagPayload isFeatureEnabled reloadFeatureFlags updateEarlyAccessFeatureEnrollment getEarlyAccessFeatures on onFeatureFlags onSurveysLoaded onSessionId getSurveys getActiveMatchingSurveys renderSurvey displaySurvey cancelPendingSurvey canRenderSurvey canRenderSurveyAsync identify setPersonProperties group resetGroups setPersonPropertiesForFlags resetPersonPropertiesForFlags setGroupPropertiesForFlags resetGroupPropertiesForFlags reset get_distinct_id getGroups get_session_id get_session_replay_url alias set_config startSessionRecording stopSessionRecording sessionRecordingStarted captureException loadToolbar get_property getSessionProperty Gr Br createPersonProfile Vr Cr Kr opt_in_capturing opt_out_capturing has_opted_in_capturing has_opted_out_capturing get_explicit_consent_status is_capturing clear_opt_in_out_capturing Hr debug O Wr getPageViewId captureTraceFeedback captureTraceMetric Rr".split(" "),n=0;n<o.length;n++)g(u,o[n]);e._i.push([i,s,a])},e.__SV=1)}(document,window.posthog||[]);
posthog.init('phc_J0Ac94FAcsmbFj0CWOAqo9tGGSE4i9F4LXXfnN796gN', {
api_host: 'https://eu.i.posthog.com',
defaults: '2025-11-30',
person_profiles: 'identified_only',
});
`,
}}
/>
</head>
<body className="bg-background text-foreground antialiased font-sans selection:bg-accent/20 selection:text-foreground">
{children}
</body>
</html>
)
}