seo: GA4, breadcrumbs JSON-LD, IndexNow post-deploy, llms.txt
- Add GA4 (G-C9J0D8FFH3) to root layout alongside Yandex.Metrika - Add BreadcrumbList JSON-LD schema to all inner pages - Add scripts/indexnow.mjs — submits 30 URLs to IndexNow + Yandex on deploy - Add indexnow to postdeploy step in package.json - Update llms.txt with all 8 services and new pages (about/clients/partners) Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -1,5 +1,6 @@
|
||||
import type { Metadata } from 'next'
|
||||
import { getDictionary, LOCALES, type Locale } from '@/lib/i18n'
|
||||
import { breadcrumbSchema } from '@/lib/breadcrumbs'
|
||||
import AboutSection from '@/components/sections/AboutSection'
|
||||
|
||||
export function generateStaticParams() {
|
||||
@@ -37,9 +38,14 @@ export default async function AboutPage({ params }: { params: Promise<{ lang: st
|
||||
const { lang: langStr } = await params
|
||||
const lang = langStr as Locale
|
||||
const d = getDictionary(lang)
|
||||
const isRu = lang === 'ru'
|
||||
return (
|
||||
<div className="pt-16">
|
||||
<AboutSection d={d} standalone />
|
||||
<script type="application/ld+json" dangerouslySetInnerHTML={{ __html: JSON.stringify(breadcrumbSchema([
|
||||
{ name: isRu ? 'Главная' : 'Home', url: `https://sag24.ru/${lang}/` },
|
||||
{ name: isRu ? 'О компании' : 'About', url: `https://sag24.ru/${lang}/about/` },
|
||||
])) }} />
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
import type { Metadata } from 'next'
|
||||
import { getDictionary, LOCALES, type Locale } from '@/lib/i18n'
|
||||
import { breadcrumbSchema } from '@/lib/breadcrumbs'
|
||||
import ClientsSection from '@/components/sections/ClientsSection'
|
||||
|
||||
export function generateStaticParams() {
|
||||
@@ -37,9 +38,14 @@ export default async function ClientsPage({ params }: { params: Promise<{ lang:
|
||||
const { lang: langStr } = await params
|
||||
const lang = langStr as Locale
|
||||
const d = getDictionary(lang)
|
||||
const isRu = lang === 'ru'
|
||||
return (
|
||||
<div className="pt-16">
|
||||
<ClientsSection d={d} standalone />
|
||||
<script type="application/ld+json" dangerouslySetInnerHTML={{ __html: JSON.stringify(breadcrumbSchema([
|
||||
{ name: isRu ? 'Главная' : 'Home', url: `https://sag24.ru/${lang}/` },
|
||||
{ name: isRu ? 'Клиенты' : 'Clients', url: `https://sag24.ru/${lang}/clients/` },
|
||||
])) }} />
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
import type { Metadata } from 'next'
|
||||
import { getDictionary, LOCALES, type Locale } from '@/lib/i18n'
|
||||
import { breadcrumbSchema } from '@/lib/breadcrumbs'
|
||||
import FaqSection from '@/components/sections/FaqSection'
|
||||
|
||||
export function generateStaticParams() {
|
||||
@@ -49,13 +50,15 @@ export default async function FaqPage({ params }: { params: Promise<{ lang: stri
|
||||
})),
|
||||
}
|
||||
|
||||
const isRu = lang === 'ru'
|
||||
return (
|
||||
<div className="pt-16">
|
||||
<FaqSection d={d} standalone />
|
||||
<script
|
||||
type="application/ld+json"
|
||||
dangerouslySetInnerHTML={{ __html: JSON.stringify(faqSchema) }}
|
||||
/>
|
||||
<script type="application/ld+json" dangerouslySetInnerHTML={{ __html: JSON.stringify(faqSchema) }} />
|
||||
<script type="application/ld+json" dangerouslySetInnerHTML={{ __html: JSON.stringify(breadcrumbSchema([
|
||||
{ name: isRu ? 'Главная' : 'Home', url: `https://sag24.ru/${lang}/` },
|
||||
{ name: 'FAQ', url: `https://sag24.ru/${lang}/faq/` },
|
||||
])) }} />
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
import type { Metadata } from 'next'
|
||||
import { getDictionary, LOCALES, type Locale } from '@/lib/i18n'
|
||||
import { breadcrumbSchema } from '@/lib/breadcrumbs'
|
||||
import ContactForm from '@/components/ui/ContactForm'
|
||||
import { Phone, Mail, MapPin } from 'lucide-react'
|
||||
|
||||
@@ -128,10 +129,11 @@ export default async function KontaktyPage({ params }: { params: Promise<{ lang:
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
<script
|
||||
type="application/ld+json"
|
||||
dangerouslySetInnerHTML={{ __html: JSON.stringify(localBusinessSchema) }}
|
||||
/>
|
||||
<script type="application/ld+json" dangerouslySetInnerHTML={{ __html: JSON.stringify(localBusinessSchema) }} />
|
||||
<script type="application/ld+json" dangerouslySetInnerHTML={{ __html: JSON.stringify(breadcrumbSchema([
|
||||
{ name: lang === 'ru' ? 'Главная' : 'Home', url: `https://sag24.ru/${lang}/` },
|
||||
{ name: lang === 'ru' ? 'Контакты' : 'Contact', url: `https://sag24.ru/${lang}/kontakty/` },
|
||||
])) }} />
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
import type { Metadata } from 'next'
|
||||
import { getDictionary, LOCALES, type Locale } from '@/lib/i18n'
|
||||
import { breadcrumbSchema } from '@/lib/breadcrumbs'
|
||||
import PartnersSection from '@/components/sections/PartnersSection'
|
||||
|
||||
export function generateStaticParams() {
|
||||
@@ -37,9 +38,14 @@ export default async function PartnersPage({ params }: { params: Promise<{ lang:
|
||||
const { lang: langStr } = await params
|
||||
const lang = langStr as Locale
|
||||
const d = getDictionary(lang)
|
||||
const isRu = lang === 'ru'
|
||||
return (
|
||||
<div className="pt-16">
|
||||
<PartnersSection d={d} standalone />
|
||||
<script type="application/ld+json" dangerouslySetInnerHTML={{ __html: JSON.stringify(breadcrumbSchema([
|
||||
{ name: isRu ? 'Главная' : 'Home', url: `https://sag24.ru/${lang}/` },
|
||||
{ name: isRu ? 'Партнёры' : 'Partners', url: `https://sag24.ru/${lang}/partners/` },
|
||||
])) }} />
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
@@ -3,6 +3,7 @@ import Link from 'next/link'
|
||||
import { notFound } from 'next/navigation'
|
||||
import { getDictionary, LOCALES, type Locale } from '@/lib/i18n'
|
||||
import { SERVICE_SLUGS } from '@/lib/services'
|
||||
import { breadcrumbSchema } from '@/lib/breadcrumbs'
|
||||
import { Server, Shield, Headphones, Camera, Network, HardDrive, Phone, Cloud, CheckCircle2, ChevronRight } from 'lucide-react'
|
||||
|
||||
const ICONS = [Server, Shield, Headphones, Camera, Network, HardDrive, Phone, Cloud]
|
||||
@@ -109,6 +110,14 @@ export default async function ServicePage({ params }: { params: Promise<{ lang:
|
||||
</Link>
|
||||
</div>
|
||||
|
||||
<script
|
||||
type="application/ld+json"
|
||||
dangerouslySetInnerHTML={{ __html: JSON.stringify(breadcrumbSchema([
|
||||
{ name: lang === 'ru' ? 'Главная' : 'Home', url: `https://sag24.ru/${lang}/` },
|
||||
{ name: lang === 'ru' ? 'Услуги' : 'Services', url: `https://sag24.ru/${lang}/uslugi/` },
|
||||
{ name: svc.title, url: `https://sag24.ru/${lang}/uslugi/${slug}/` },
|
||||
])) }}
|
||||
/>
|
||||
<script
|
||||
type="application/ld+json"
|
||||
dangerouslySetInnerHTML={{
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
import type { Metadata } from 'next'
|
||||
import Link from 'next/link'
|
||||
import { getDictionary, LOCALES, type Locale } from '@/lib/i18n'
|
||||
import { breadcrumbSchema } from '@/lib/breadcrumbs'
|
||||
import { Server, Shield, Headphones, Camera, Network, HardDrive, Phone, Cloud } from 'lucide-react'
|
||||
|
||||
export function generateStaticParams() {
|
||||
@@ -78,6 +79,10 @@ export default async function UslugiPage({ params }: { params: Promise<{ lang: s
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
<script type="application/ld+json" dangerouslySetInnerHTML={{ __html: JSON.stringify(breadcrumbSchema([
|
||||
{ name: lang === 'ru' ? 'Главная' : 'Home', url: `https://sag24.ru/${lang}/` },
|
||||
{ name: lang === 'ru' ? 'Услуги' : 'Services', url: `https://sag24.ru/${lang}/uslugi/` },
|
||||
])) }} />
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
@@ -24,6 +24,14 @@ export default function RootLayout({ children }: { children: React.ReactNode })
|
||||
<link rel="icon" type="image/svg+xml" href="/favicon.svg" />
|
||||
<link rel="apple-touch-icon" href="/apple-touch-icon.png" />
|
||||
<Script src="https://challenges.cloudflare.com/turnstile/v0/api.js" strategy="lazyOnload" />
|
||||
{/* Google Analytics GA4 */}
|
||||
<Script src="https://www.googletagmanager.com/gtag/js?id=G-C9J0D8FFH3" strategy="afterInteractive" />
|
||||
<Script id="ga4" strategy="afterInteractive">{`
|
||||
window.dataLayer = window.dataLayer || [];
|
||||
function gtag(){dataLayer.push(arguments);}
|
||||
gtag('js', new Date());
|
||||
gtag('config', 'G-C9J0D8FFH3');
|
||||
`}</Script>
|
||||
{/* Yandex.Metrika */}
|
||||
<Script id="ym" strategy="afterInteractive">{`
|
||||
(function(m,e,t,r,i,k,a){m[i]=m[i]||function(){(m[i].a=m[i].a||[]).push(arguments)};
|
||||
|
||||
Reference in New Issue
Block a user