Files
pushkinohistory-ru-v2/src/layouts/BaseLayout.astro
striker 3d42a588d4
All checks were successful
deploy / deploy (push) Successful in 1m0s
feat(schema): add creator entity (hhivp.com) to WebSite JSON-LD
Entity-сигнал для AI Overviews / Я.Нейро о тех-партнёрстве.
Связывает сайт с разработчиком через @id графа.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-24 05:07:49 +03:00

138 lines
4.1 KiB
Plaintext
Raw 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.
---
import '../styles/global.css';
import Header from '../components/Header.astro';
import Sidebar from '../components/Sidebar.astro';
import Footer from '../components/Footer.astro';
import CookieConsent from '../components/CookieConsent.astro';
import Analytics from '../components/Analytics.astro';
import { SITE_TITLE, SITE_DESCRIPTION, SITE_URL, SITE_LANG } from '../consts';
interface Props {
title?: string;
description?: string;
ogImage?: string;
noSidebar?: boolean;
canonical?: string;
}
const {
title,
description = SITE_DESCRIPTION,
ogImage = '/og-image.png',
noSidebar = false,
canonical,
} = Astro.props;
const fullTitle = title ? `${title} — ${SITE_TITLE}` : SITE_TITLE;
const url = canonical ?? new URL(Astro.url.pathname, SITE_URL).toString();
const ogImageUrl = new URL(ogImage, SITE_URL).toString();
const jsonLd = {
'@context': 'https://schema.org',
'@graph': [
{
'@type': 'WebSite',
'@id': `${SITE_URL}/#website`,
url: `${SITE_URL}/`,
name: SITE_TITLE,
description: SITE_DESCRIPTION,
inLanguage: 'ru-RU',
publisher: { '@id': `${SITE_URL}/#publisher` },
// creator — тех-партнёр (hhivp.com). Entity-сигнал для AI Overviews.
creator: {
'@type': 'Organization',
'@id': 'https://hhivp.com/#organization',
name: 'ООО «АйТи Решения»',
url: 'https://hhivp.com/',
sameAs: ['https://hhivp.com'],
},
},
{
'@type': 'NewsMediaOrganization',
'@id': `${SITE_URL}/#publisher`,
name: SITE_TITLE,
url: `${SITE_URL}/`,
logo: {
'@type': 'ImageObject',
url: `${SITE_URL}/favicon.svg`,
},
description:
'Краеведческое медиа: история, новости и фотолетопись подмосковного города Пушкино — от давних времён до наших дней.',
},
],
};
---
<!doctype html>
<html lang={SITE_LANG}>
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>{fullTitle}</title>
<meta name="description" content={description} />
<link rel="canonical" href={url} />
<link rel="icon" type="image/svg+xml" href="/favicon.svg" />
<link rel="alternate" type="application/rss+xml" title="История города Пушкино — RSS" href="/feed.xml" />
<meta property="og:type" content="website" />
<meta property="og:title" content={fullTitle} />
<meta property="og:description" content={description} />
<meta property="og:url" content={url} />
<meta property="og:image" content={ogImageUrl} />
<meta property="og:locale" content="ru_RU" />
<meta property="og:site_name" content={SITE_TITLE} />
<meta name="twitter:card" content="summary_large_image" />
<script type="application/ld+json" is:inline set:html={JSON.stringify(jsonLd)} />
<!--
Speculation Rules API (Chromium 122+) — prerender same-origin pages on
hover/pointerdown for near-instant navigation.
-->
<script type="speculationrules" is:inline set:html={JSON.stringify({
prerender: [
{
where: {
and: [
{ href_matches: '/*' },
{ not: { href_matches: '/assets/*' } },
{ not: { href_matches: '/uploads/*' } },
{ not: { href_matches: '/api/*' } },
{ not: { href_matches: '/sitemap*' } },
{ not: { href_matches: '/feed*' } },
{ not: { href_matches: '/llms*' } }
]
},
eagerness: 'moderate'
}
]
})} />
<Analytics />
</head>
<body>
<Header />
<div class="container">
{noSidebar ? (
<main class="layout-single">
<slot />
</main>
) : (
<div class="layout-grid">
<main><slot /></main>
<Sidebar />
</div>
)}
</div>
<Footer />
<CookieConsent />
</body>
</html>
<style>
.layout-single {
max-width: var(--reading-max);
margin: 2rem auto;
}
</style>