-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathBaseHead.astro
More file actions
220 lines (191 loc) · 7.34 KB
/
Copy pathBaseHead.astro
File metadata and controls
220 lines (191 loc) · 7.34 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
---
// Import the global.css file here so that it is included on
// all pages through the use of the <BaseHead /> component.
import '../styles/global.css';
import { Font } from 'astro:assets';
import { SITE_TITLE, SITE_DESCRIPTION, AUTHOR, SEO_CONFIG } from '../consts';
import { generateMetaTags, DEFAULT_LOCALE } from '../utils/seo';
import { ogLocaleAlternatesFromHreflang } from '../utils/ogLocale';
import { assetConfig } from '../config/assets';
interface Props {
title: string;
description?: string;
path?: string;
heroImage?: string; // Primary image for social sharing
imageAlt?: string;
pubDate?: Date;
updatedDate?: Date;
author?: string;
keywords?: string[];
locale?: string;
type?: 'website' | 'article';
robots?: string;
hreflangAlternates?: Array<{ hreflang: string; href: string }>;
htmlLang?: 'en' | 'es';
}
const {
title,
description = SITE_DESCRIPTION,
path,
heroImage,
imageAlt,
pubDate,
updatedDate,
author = AUTHOR.name,
keywords = [],
locale = DEFAULT_LOCALE,
type,
robots,
hreflangAlternates = [],
htmlLang = 'en',
} = Astro.props;
// Generate optimized meta tags with proper heroImage prioritization
const metaTags = generateMetaTags({
title,
description,
path: path || Astro.url.pathname,
heroImage,
imageAlt,
author,
keywords,
pubDate,
updatedDate,
locale,
type,
robots,
});
const ogLocaleAlternates = ogLocaleAlternatesFromHreflang(hreflangAlternates, metaTags.locale);
// Format dates for meta tags
const pubDateISO = pubDate?.toISOString();
const updatedDateISO = updatedDate?.toISOString();
---
<!-- Character Set & Viewport -->
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<meta name="viewport-height" content="100vh" />
<!-- Font preloading handled by Astro Fonts API -->
<!-- Critical Resource Preloading -->
{heroImage && <link rel="preload" href={heroImage} as="image" />}
{!heroImage && <link rel="preload" href="/images/default.avif" as="image" />}
<!-- Theme & Color -->
<meta name="theme-color" content="#ffffff" media="(prefers-color-scheme: light)" />
<meta name="theme-color" content="#0a0a0a" media="(prefers-color-scheme: dark)" />
<meta name="color-scheme" content="light dark" />
<!-- Astro 6 Fonts API -->
<Font cssVariable="--font-sans" preload />
<Font cssVariable="--font-heading" preload />
<Font cssVariable="--font-serif" />
<Font cssVariable="--font-mono" />
<!-- Theme Initialization Script - Prevents FOUC -->
<script is:inline>
// Theme initialization - must run before any content renders
(function () {
try {
// Get stored theme preference or default to system preference
const storedTheme = localStorage.getItem('theme');
const systemPrefersDark = window.matchMedia('(prefers-color-scheme: dark)').matches;
// Determine initial theme
let theme = 'light';
if (storedTheme === 'dark' || (!storedTheme && systemPrefersDark)) {
theme = 'dark';
}
// Apply theme immediately to prevent FOUC
if (theme === 'dark') {
document.documentElement.classList.add('dark');
} else {
document.documentElement.classList.remove('dark');
}
// Update meta theme-color
const metaThemeColor = document.querySelector('meta[name="theme-color"]');
if (metaThemeColor) {
metaThemeColor.setAttribute('content', theme === 'dark' ? '#0a0a0a' : '#ffffff');
}
} catch (error) {
// Fallback to system preference if localStorage fails
if (window.matchMedia('(prefers-color-scheme: dark)').matches) {
document.documentElement.classList.add('dark');
}
}
})();
</script>
<!-- Favicon & Icons -->
<link rel="icon" type="image/x-icon" href="/favicon.ico" sizes="any" />
<link rel="icon" type="image/svg+xml" href={assetConfig.images.favicon} />
<link rel="icon" type="image/png" href="/favicon-192x192.png" sizes="192x192" />
<link rel="icon" type="image/png" href="/favicon-512x512.png" sizes="512x512" />
<link rel="apple-touch-icon" href="/apple-touch-icon.png" />
<link rel="manifest" href={assetConfig.manifest} />
<!-- Language & Generator -->
<meta http-equiv="content-language" content={htmlLang} />
<meta name="generator" content={Astro.generator} />
<!-- Canonical URL -->
<link rel="canonical" href={metaTags.canonical} />
{
hreflangAlternates.map((alternate) => (
<link rel="alternate" hreflang={alternate.hreflang} href={alternate.href} />
))
}
<!-- RSS Feed -->
<link
rel="alternate"
type="application/rss+xml"
title={`${SITE_TITLE} - RSS Feed`}
href={new URL('rss.xml', Astro.site)}
/>
<!-- JSON Feed -->
<link
rel="alternate"
type="application/feed+json"
title={`${SITE_TITLE} - JSON Feed`}
href={new URL('feed.json', Astro.site)}
/>
<!-- Sitemap -->
<link rel="sitemap" href={new URL('sitemap-index.xml', Astro.site)} />
<!-- Primary Meta Tags -->
<title>{metaTags.title}</title>
<meta name="description" content={metaTags.description} />
<meta name="robots" content={metaTags.robots} />
{metaTags.keywords && <meta name="keywords" content={metaTags.keywords} />}
<meta name="author" content={metaTags.author} />
<!-- Google Site Verification -->
<meta name="google-site-verification" content={SEO_CONFIG.googleSiteVerification} />
<meta name="msvalidate.01" content="30A0A57EBF1AAC2E32B5F6FB4F8C0092" />
<!-- Open Graph / Facebook -->
<meta property="og:type" content={metaTags.ogType} />
<meta property="og:url" content={metaTags.canonical} />
<meta property="og:title" content={metaTags.title} />
<meta property="og:description" content={metaTags.description} />
<meta property="og:image" content={metaTags.ogImage} />
<meta property="og:image:alt" content={metaTags.ogImageAlt} />
<meta property="og:locale" content={metaTags.locale} />
{
ogLocaleAlternates.map((ogLocale) => (
<meta property="og:locale:alternate" content={ogLocale} />
))
}
<meta property="og:site_name" content={SITE_TITLE} />
<!-- Twitter -->
<meta property="twitter:card" content="summary_large_image" />
<meta property="twitter:url" content={metaTags.canonical} />
<meta property="twitter:title" content={metaTags.title} />
<meta property="twitter:description" content={metaTags.description} />
<meta property="twitter:image" content={metaTags.ogImage} />
<meta property="twitter:image:alt" content={metaTags.ogImageAlt} />
<meta name="twitter:creator" content={SEO_CONFIG.twitterHandle} />
<meta name="twitter:site" content={SEO_CONFIG.twitterHandle} />
<!-- Article Specific Meta Tags -->
{pubDateISO && <meta property="article:published_time" content={pubDateISO} />}
{updatedDateISO && <meta property="article:modified_time" content={updatedDateISO} />}
{metaTags.keywords && <meta property="article:tag" content={metaTags.keywords} />}
<meta property="article:author" content={AUTHOR.url} />
<meta property="article:section" content="Notes" />
<!-- Additional Meta Tags -->
<meta name="format-detection" content="telephone=no" />
<meta name="referrer" content="strict-origin-when-cross-origin" />
<!-- Preconnect to external domains for performance -->
<!-- Remark42 comments: preconnect is handled dynamically via the embed script -->
<link rel="preconnect" href="https://vitals.vercel-insights.com" />
<link rel="preconnect" href="https://va.vercel-scripts.com" />
<!-- DNS Prefetch for external resources -->
<link rel="dns-prefetch" href="//vitals.vercel-insights.com" />
<link rel="dns-prefetch" href="//va.vercel-scripts.com" />