@flightdev/seo 0.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2024-2026 Flight Contributors
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,403 @@
1
+ # @flight-framework/seo
2
+
3
+ Native SEO and head management for Flight Framework. Zero dependencies, framework-agnostic, SSR-first.
4
+
5
+ ## Features
6
+
7
+ - **Head Management** - Tag deduplication, ordering, and efficient rendering
8
+ - **Meta Tags** - Basic meta, robots, verification, viewport
9
+ - **Open Graph** - Full OG protocol support including article, product, profile
10
+ - **Twitter Cards** - Summary, large image, app, and player cards
11
+ - **JSON-LD** - Type-safe structured data for rich results
12
+ - **Sitemap Generation** - XML sitemaps with image, video, and news support
13
+ - **robots.txt** - Configurable crawler directives
14
+ - **Framework Integrations** - React, Vue, Solid, Svelte
15
+
16
+ ## Installation
17
+
18
+ ```bash
19
+ npm install @flight-framework/seo
20
+ ```
21
+
22
+ ## Quick Start
23
+
24
+ ### Core API
25
+
26
+ ```typescript
27
+ import { createSEO, defineMeta } from '@flight-framework/seo';
28
+
29
+ const seo = createSEO({
30
+ baseUrl: 'https://example.com',
31
+ titleTemplate: '%s | My Site',
32
+ defaultTitle: 'My Site',
33
+ });
34
+
35
+ const metadata = defineMeta({
36
+ title: 'About Us',
37
+ description: 'Learn more about our company',
38
+ canonical: '/about',
39
+ openGraph: {
40
+ type: 'website',
41
+ images: [{ url: '/og.jpg', width: 1200, height: 630 }],
42
+ },
43
+ twitter: {
44
+ card: 'summary_large_image',
45
+ },
46
+ });
47
+
48
+ const { html, tags } = seo.render(metadata);
49
+ // Insert `html` into your document head
50
+ ```
51
+
52
+ ### React
53
+
54
+ ```tsx
55
+ import { SEO, JsonLd } from '@flight-framework/seo/react';
56
+
57
+ export default function ProductPage({ product }) {
58
+ return (
59
+ <>
60
+ <SEO
61
+ title={product.name}
62
+ description={product.description}
63
+ openGraph={{
64
+ type: 'product',
65
+ images: [{ url: product.image }],
66
+ }}
67
+ />
68
+ <JsonLd
69
+ data={{
70
+ '@type': 'Product',
71
+ name: product.name,
72
+ offers: {
73
+ '@type': 'Offer',
74
+ price: product.price,
75
+ priceCurrency: 'USD',
76
+ },
77
+ }}
78
+ />
79
+ <main>{/* Page content */}</main>
80
+ </>
81
+ );
82
+ }
83
+ ```
84
+
85
+ ### Vue
86
+
87
+ ```vue
88
+ <script setup>
89
+ import { useSEO, useJsonLd } from '@flight-framework/seo/vue';
90
+
91
+ const product = defineProps(['product']);
92
+
93
+ useSEO({
94
+ title: product.name,
95
+ description: product.description,
96
+ openGraph: {
97
+ type: 'product',
98
+ images: [{ url: product.image }],
99
+ },
100
+ });
101
+
102
+ useJsonLd({
103
+ '@type': 'Product',
104
+ name: product.name,
105
+ offers: {
106
+ '@type': 'Offer',
107
+ price: product.price,
108
+ priceCurrency: 'USD',
109
+ },
110
+ });
111
+ </script>
112
+ ```
113
+
114
+ ### Solid
115
+
116
+ ```tsx
117
+ import { SEO, JsonLd } from '@flight-framework/seo/solid';
118
+
119
+ export default function ProductPage(props) {
120
+ return (
121
+ <>
122
+ <SEO
123
+ title={props.product.name}
124
+ description={props.product.description}
125
+ />
126
+ <JsonLd data={{ '@type': 'Product', name: props.product.name }} />
127
+ <main>...</main>
128
+ </>
129
+ );
130
+ }
131
+ ```
132
+
133
+ ### Svelte
134
+
135
+ ```svelte
136
+ <script>
137
+ import { generateMetadataHtml, createJsonLdScript } from '@flight-framework/seo/svelte';
138
+
139
+ export let product;
140
+ </script>
141
+
142
+ <svelte:head>
143
+ {@html generateMetadataHtml({
144
+ title: product.name,
145
+ description: product.description,
146
+ openGraph: { type: 'product' }
147
+ })}
148
+ {@html createJsonLdScript({
149
+ '@type': 'Product',
150
+ name: product.name
151
+ })}
152
+ </svelte:head>
153
+ ```
154
+
155
+ ## API Reference
156
+
157
+ ### createSEO(config?)
158
+
159
+ Create an SEO service instance.
160
+
161
+ ```typescript
162
+ const seo = createSEO({
163
+ baseUrl: 'https://example.com',
164
+ titleTemplate: '%s | My Site',
165
+ defaultTitle: 'My Site',
166
+ defaultOpenGraph: {
167
+ siteName: 'My Site',
168
+ locale: 'en_US',
169
+ },
170
+ defaultTwitter: {
171
+ site: '@mysite',
172
+ },
173
+ });
174
+ ```
175
+
176
+ ### defineMeta(metadata)
177
+
178
+ Type-safe metadata definition.
179
+
180
+ ```typescript
181
+ const metadata = defineMeta({
182
+ title: 'Page Title',
183
+ description: 'Page description',
184
+ keywords: ['keyword1', 'keyword2'],
185
+ author: 'Author Name',
186
+ canonical: 'https://example.com/page',
187
+ robots: { index: true, follow: true },
188
+ openGraph: { /* ... */ },
189
+ twitter: { /* ... */ },
190
+ });
191
+ ```
192
+
193
+ ### Metadata Types
194
+
195
+ ```typescript
196
+ interface Metadata {
197
+ // Basic
198
+ title?: string;
199
+ titleTemplate?: string;
200
+ description?: string;
201
+ keywords?: string | string[];
202
+ author?: string;
203
+ canonical?: string;
204
+
205
+ // Robots
206
+ robots?: RobotsMeta | string;
207
+ googleBot?: RobotsMeta | string;
208
+
209
+ // Open Graph
210
+ openGraph?: {
211
+ type?: 'website' | 'article' | 'product' | ...;
212
+ title?: string;
213
+ description?: string;
214
+ url?: string;
215
+ siteName?: string;
216
+ locale?: string;
217
+ images?: OpenGraphImage[];
218
+ article?: OpenGraphArticle;
219
+ product?: OpenGraphProduct;
220
+ };
221
+
222
+ // Twitter
223
+ twitter?: {
224
+ card?: 'summary' | 'summary_large_image' | 'app' | 'player';
225
+ title?: string;
226
+ description?: string;
227
+ site?: string;
228
+ creator?: string;
229
+ image?: TwitterCardImage | string;
230
+ };
231
+ }
232
+ ```
233
+
234
+ ## JSON-LD Structured Data
235
+
236
+ ```typescript
237
+ import {
238
+ createJsonLd,
239
+ articleJsonLd,
240
+ productJsonLd,
241
+ breadcrumbJsonLd,
242
+ faqJsonLd,
243
+ } from '@flight-framework/seo/json-ld';
244
+
245
+ // Generic
246
+ const jsonLd = createJsonLd({
247
+ '@type': 'Organization',
248
+ name: 'My Company',
249
+ url: 'https://example.com',
250
+ });
251
+
252
+ // Article
253
+ const article = articleJsonLd({
254
+ headline: 'Article Title',
255
+ datePublished: '2026-01-10',
256
+ author: { '@type': 'Person', name: 'Author' },
257
+ publisher: { '@type': 'Organization', name: 'Publisher' },
258
+ });
259
+
260
+ // Product
261
+ const product = productJsonLd({
262
+ name: 'Widget',
263
+ description: 'A great widget',
264
+ offers: {
265
+ '@type': 'Offer',
266
+ price: 9.99,
267
+ priceCurrency: 'USD',
268
+ availability: 'InStock',
269
+ },
270
+ });
271
+
272
+ // Breadcrumb
273
+ const breadcrumb = breadcrumbJsonLd([
274
+ { name: 'Home', url: '/' },
275
+ { name: 'Products', url: '/products' },
276
+ { name: 'Widget' },
277
+ ]);
278
+
279
+ // FAQ
280
+ const faq = faqJsonLd([
281
+ { question: 'What is this?', answer: 'A great product.' },
282
+ { question: 'How much?', answer: '$9.99' },
283
+ ]);
284
+ ```
285
+
286
+ ## Sitemap Generation
287
+
288
+ ```typescript
289
+ import { createSitemap, createSitemapIndex } from '@flight-framework/seo/sitemap';
290
+
291
+ const sitemap = createSitemap({
292
+ baseUrl: 'https://example.com',
293
+ pretty: true,
294
+ });
295
+
296
+ // Add URLs
297
+ sitemap.add('/', { priority: 1.0, changefreq: 'daily' });
298
+ sitemap.add('/about', { priority: 0.8 });
299
+ sitemap.add('/products/widget', {
300
+ lastmod: new Date(),
301
+ priority: 0.7,
302
+ images: [{ loc: '/images/widget.jpg', title: 'Widget' }],
303
+ });
304
+
305
+ // Generate XML
306
+ const xml = sitemap.generate();
307
+
308
+ // For large sites, use sitemap index
309
+ const index = createSitemapIndex();
310
+ index.add('https://example.com/sitemap-1.xml');
311
+ index.add('https://example.com/sitemap-2.xml');
312
+ const indexXml = index.generate();
313
+ ```
314
+
315
+ ## robots.txt Generation
316
+
317
+ ```typescript
318
+ import { createRobots, standardRobots } from '@flight-framework/seo/robots';
319
+
320
+ // Custom
321
+ const robots = createRobots();
322
+ robots.allow('*', '/');
323
+ robots.disallow('*', '/admin');
324
+ robots.disallow('*', '/api');
325
+ robots.addSitemap('https://example.com/sitemap.xml');
326
+ const txt = robots.generate();
327
+
328
+ // Standard preset
329
+ const standard = standardRobots({
330
+ sitemapUrl: 'https://example.com/sitemap.xml',
331
+ blockPaths: ['/private'],
332
+ });
333
+ ```
334
+
335
+ ## SSR Integration
336
+
337
+ ```typescript
338
+ // In your server entry
339
+ import { createSEO, createHeadManager } from '@flight-framework/seo';
340
+
341
+ const seo = createSEO({ baseUrl: 'https://example.com' });
342
+
343
+ export function render(url: string, metadata: Metadata): string {
344
+ const { html: headHtml } = seo.render(metadata);
345
+
346
+ return `
347
+ <!DOCTYPE html>
348
+ <html>
349
+ <head>
350
+ ${headHtml}
351
+ </head>
352
+ <body>
353
+ <!-- app content -->
354
+ </body>
355
+ </html>
356
+ `;
357
+ }
358
+ ```
359
+
360
+ ## Dynamic Metadata
361
+
362
+ ```typescript
363
+ // src/routes/products/[id].page.tsx
364
+ import { defineMeta } from '@flight-framework/seo';
365
+
366
+ export async function generateMetadata({ params }) {
367
+ const product = await getProduct(params.id);
368
+
369
+ return defineMeta({
370
+ title: product.name,
371
+ description: product.description,
372
+ openGraph: {
373
+ type: 'product',
374
+ images: [{ url: product.image }],
375
+ },
376
+ });
377
+ }
378
+
379
+ export default function ProductPage({ product }) {
380
+ return <main>{/* content */}</main>;
381
+ }
382
+ ```
383
+
384
+ ## Best Practices
385
+
386
+ 1. **Always set title and description** - These are essential for SEO
387
+ 2. **Use canonical URLs** - Prevent duplicate content issues
388
+ 3. **Provide Open Graph images** - 1200x630px recommended for social sharing
389
+ 4. **Add structured data** - Improves rich results in search
390
+ 5. **Generate sitemaps** - Help search engines discover your pages
391
+ 6. **Configure robots.txt** - Control crawler access
392
+
393
+ ## Related
394
+
395
+ - [Flight Framework](https://github.com/flight-framework/flight)
396
+ - [Open Graph Protocol](https://ogp.me/)
397
+ - [Twitter Cards](https://developer.twitter.com/en/docs/twitter-for-websites/cards)
398
+ - [Schema.org](https://schema.org/)
399
+ - [Google Rich Results](https://search.google.com/test/rich-results)
400
+
401
+ ## License
402
+
403
+ MIT License
@@ -0,0 +1,282 @@
1
+ import { H as HtmlTag, R as RenderedHead, M as Metadata, V as VerificationMeta, O as OpenGraphMeta, T as TwitterCardMeta, S as SEOConfig, a as SEOService } from './types-BBIMJIqz.js';
2
+ export { A as AlternateLink, I as IconMeta, h as OpenGraphArticle, g as OpenGraphAudio, j as OpenGraphBook, e as OpenGraphImage, k as OpenGraphProduct, i as OpenGraphProfile, d as OpenGraphType, f as OpenGraphVideo, b as ResolvedMetadata, c as RobotsMeta, o as TwitterCardApp, m as TwitterCardImage, n as TwitterCardPlayer, l as TwitterCardType } from './types-BBIMJIqz.js';
3
+
4
+ /**
5
+ * @flightdev/seo - Head Manager
6
+ *
7
+ * Server-side head management with tag deduplication,
8
+ * ordering, and efficient rendering.
9
+ *
10
+ * Designed for SSR-first with O(1) deduplication.
11
+ */
12
+
13
+ /**
14
+ * Head Manager for SSR
15
+ *
16
+ * Manages head tags with:
17
+ * - O(1) deduplication using Map
18
+ * - Deterministic ordering
19
+ * - Efficient string concatenation
20
+ */
21
+ declare class HeadManager {
22
+ private tags;
23
+ private frozen;
24
+ /**
25
+ * Add a tag to the head
26
+ */
27
+ addTag(tag: HtmlTag): this;
28
+ /**
29
+ * Add multiple tags
30
+ */
31
+ addTags(tags: HtmlTag[]): this;
32
+ /**
33
+ * Remove a tag by key
34
+ */
35
+ removeTag(key: string): this;
36
+ /**
37
+ * Check if a tag exists
38
+ */
39
+ hasTag(key: string): boolean;
40
+ /**
41
+ * Get a tag by key
42
+ */
43
+ getTag(key: string): HtmlTag | undefined;
44
+ /**
45
+ * Get all tags
46
+ */
47
+ getTags(): HtmlTag[];
48
+ /**
49
+ * Clear all tags
50
+ */
51
+ clear(): this;
52
+ /**
53
+ * Freeze the manager (no more modifications)
54
+ */
55
+ freeze(): this;
56
+ /**
57
+ * Check if frozen
58
+ */
59
+ isFrozen(): boolean;
60
+ /**
61
+ * Render all tags to HTML
62
+ */
63
+ render(): RenderedHead;
64
+ }
65
+ /**
66
+ * Render a single tag to HTML
67
+ */
68
+ declare function renderTag(tag: HtmlTag): string;
69
+ /**
70
+ * Render multiple tags to HTML
71
+ */
72
+ declare function renderTags(tags: HtmlTag[]): string;
73
+ /**
74
+ * Create a new HeadManager instance
75
+ */
76
+ declare function createHeadManager(): HeadManager;
77
+ /**
78
+ * SSR head context for passing data between components
79
+ */
80
+ interface HeadContext {
81
+ manager: HeadManager;
82
+ metadata: Metadata;
83
+ }
84
+ /**
85
+ * Set the current head context (call at request start)
86
+ */
87
+ declare function setHeadContext(context: HeadContext): void;
88
+ /**
89
+ * Get the current head context
90
+ */
91
+ declare function getHeadContext(): HeadContext | null;
92
+ /**
93
+ * Clear the current head context (call at request end)
94
+ */
95
+ declare function clearHeadContext(): void;
96
+ /**
97
+ * Run a function with a head context
98
+ */
99
+ declare function withHeadContext<T>(context: HeadContext, fn: () => T): T;
100
+
101
+ /**
102
+ * @flightdev/seo - Meta Tag Generation
103
+ *
104
+ * Generates meta tags from Metadata configuration.
105
+ * Handles basic meta, robots, viewport, and verification tags.
106
+ */
107
+
108
+ /**
109
+ * Generate title tag
110
+ */
111
+ declare function generateTitleTag(title: string | undefined, template?: string, defaultTitle?: string): HtmlTag | null;
112
+ /**
113
+ * Generate charset meta tag
114
+ */
115
+ declare function generateCharsetTag(charset?: string): HtmlTag;
116
+ /**
117
+ * Generate viewport meta tag
118
+ */
119
+ declare function generateViewportTag(viewport: Metadata['viewport']): HtmlTag | null;
120
+ /**
121
+ * Generate description meta tag
122
+ */
123
+ declare function generateDescriptionTag(description: string | undefined): HtmlTag | null;
124
+ /**
125
+ * Generate keywords meta tag
126
+ */
127
+ declare function generateKeywordsTag(keywords: string | string[] | undefined): HtmlTag | null;
128
+ /**
129
+ * Generate author meta tag
130
+ */
131
+ declare function generateAuthorTag(author: string | undefined): HtmlTag | null;
132
+ /**
133
+ * Generate theme-color meta tag(s)
134
+ */
135
+ declare function generateThemeColorTags(themeColor: Metadata['themeColor']): HtmlTag[];
136
+ /**
137
+ * Generate robots meta tag
138
+ */
139
+ declare function generateRobotsTag(robots: Metadata['robots']): HtmlTag | null;
140
+ /**
141
+ * Generate googlebot meta tag
142
+ */
143
+ declare function generateGooglebotTag(googleBot: Metadata['googleBot']): HtmlTag | null;
144
+ /**
145
+ * Generate verification meta tags
146
+ */
147
+ declare function generateVerificationTags(verification: VerificationMeta | undefined): HtmlTag[];
148
+ /**
149
+ * Generate canonical link tag
150
+ */
151
+ declare function generateCanonicalTag(canonical: string | undefined): HtmlTag | null;
152
+ /**
153
+ * Generate alternate link tags
154
+ */
155
+ declare function generateAlternateTags(alternates: Metadata['alternates']): HtmlTag[];
156
+ /**
157
+ * Generate all basic meta tags from Metadata
158
+ */
159
+ declare function generateMetaTags(metadata: Metadata, options?: {
160
+ titleTemplate?: string;
161
+ defaultTitle?: string;
162
+ }): HtmlTag[];
163
+
164
+ /**
165
+ * @flightdev/seo - Open Graph Tags
166
+ *
167
+ * Generates Open Graph protocol meta tags for rich social sharing.
168
+ * Supports all OG types: website, article, product, profile, etc.
169
+ */
170
+
171
+ /**
172
+ * Generate all Open Graph meta tags
173
+ */
174
+ declare function generateOpenGraphTags(og: OpenGraphMeta | undefined): HtmlTag[];
175
+ /**
176
+ * Generate minimal Open Graph tags (for fallback from metadata)
177
+ */
178
+ declare function generateOpenGraphFallback(title: string | undefined, description: string | undefined, url: string | undefined): HtmlTag[];
179
+
180
+ /**
181
+ * @flightdev/seo - Twitter Card Tags
182
+ *
183
+ * Generates Twitter Card meta tags for rich Twitter sharing.
184
+ * Supports summary, summary_large_image, app, and player cards.
185
+ */
186
+
187
+ /**
188
+ * Generate all Twitter Card meta tags
189
+ */
190
+ declare function generateTwitterTags(twitter: TwitterCardMeta | undefined): HtmlTag[];
191
+ /**
192
+ * Generate minimal Twitter Card tags (for fallback)
193
+ */
194
+ declare function generateTwitterFallback(title: string | undefined, description: string | undefined, image: string | undefined, cardType?: TwitterCardMeta['card']): HtmlTag[];
195
+
196
+ /**
197
+ * @flightdev/seo
198
+ *
199
+ * Native SEO and head management for Flight Framework.
200
+ * Zero dependencies, framework-agnostic, SSR-first.
201
+ *
202
+ * Features:
203
+ * - Head management with deduplication
204
+ * - Meta tags (basic, robots, verification)
205
+ * - Open Graph protocol
206
+ * - Twitter Cards
207
+ * - JSON-LD structured data
208
+ * - Sitemap generation
209
+ * - robots.txt generation
210
+ *
211
+ * @example
212
+ * ```typescript
213
+ * import { createSEO, defineMeta } from '@flightdev/seo';
214
+ *
215
+ * const seo = createSEO({ baseUrl: 'https://example.com' });
216
+ *
217
+ * const metadata = defineMeta({
218
+ * title: 'My Page',
219
+ * description: 'Page description',
220
+ * openGraph: {
221
+ * type: 'website',
222
+ * images: [{ url: '/og.jpg', width: 1200, height: 630 }],
223
+ * },
224
+ * });
225
+ *
226
+ * const { html } = seo.render(metadata);
227
+ * ```
228
+ */
229
+
230
+ /**
231
+ * Create an SEO service
232
+ *
233
+ * @example
234
+ * ```typescript
235
+ * const seo = createSEO({
236
+ * baseUrl: 'https://example.com',
237
+ * titleTemplate: '%s | My Site',
238
+ * defaultTitle: 'My Site',
239
+ * });
240
+ *
241
+ * const { html } = seo.render({
242
+ * title: 'About Us',
243
+ * description: 'Learn more about us',
244
+ * });
245
+ * ```
246
+ */
247
+ declare function createSEO(config?: SEOConfig): SEOService;
248
+ /**
249
+ * Define metadata with type safety
250
+ *
251
+ * @example
252
+ * ```typescript
253
+ * const metadata = defineMeta({
254
+ * title: 'Product Name',
255
+ * description: 'Product description',
256
+ * openGraph: {
257
+ * type: 'product',
258
+ * images: [{ url: '/product.jpg' }],
259
+ * },
260
+ * });
261
+ * ```
262
+ */
263
+ declare function defineMeta(metadata: Metadata): Metadata;
264
+ /**
265
+ * Merge parent and child metadata
266
+ * Child values override parent values
267
+ * Arrays are replaced, not merged
268
+ */
269
+ declare function mergeMetadata(parent: Metadata, child: Metadata): Metadata;
270
+ /**
271
+ * Type for async metadata generation function
272
+ */
273
+ type GenerateMetadataFn<TParams = Record<string, string>> = (context: {
274
+ params: TParams;
275
+ searchParams?: Record<string, string | string[]>;
276
+ }) => Metadata | Promise<Metadata>;
277
+ /**
278
+ * Version constant
279
+ */
280
+ declare const VERSION = "0.1.0";
281
+
282
+ export { type GenerateMetadataFn, type HeadContext, HeadManager, HtmlTag, Metadata, OpenGraphMeta, RenderedHead, SEOConfig, SEOService, TwitterCardMeta, VERSION, VerificationMeta, clearHeadContext, createHeadManager, createSEO, defineMeta, generateAlternateTags, generateAuthorTag, generateCanonicalTag, generateCharsetTag, generateDescriptionTag, generateGooglebotTag, generateKeywordsTag, generateMetaTags, generateOpenGraphFallback, generateOpenGraphTags, generateRobotsTag, generateThemeColorTags, generateTitleTag, generateTwitterFallback, generateTwitterTags, generateVerificationTags, generateViewportTag, getHeadContext, mergeMetadata, renderTag, renderTags, setHeadContext, withHeadContext };