@lexingtonthemes/seo 0.1.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/README.md +225 -0
- package/index.ts +7 -0
- package/package.json +58 -0
- package/src/AstroSeo.astro +42 -0
- package/src/__test__/buildTags.test.ts +441 -0
- package/src/types.ts +455 -0
- package/src/utils/buildTags.ts +457 -0
package/README.md
ADDED
|
@@ -0,0 +1,225 @@
|
|
|
1
|
+
# @lexingtonthemes/seo
|
|
2
|
+
|
|
3
|
+
SEO component for Astro projects.
|
|
4
|
+
|
|
5
|
+
This package renders SEO `<meta>` and `<link>` tags in your page `<head>` using a single `AstroSeo` component.
|
|
6
|
+
|
|
7
|
+
## Install
|
|
8
|
+
|
|
9
|
+
```bash
|
|
10
|
+
npm i @lexingtonthemes/seo
|
|
11
|
+
```
|
|
12
|
+
|
|
13
|
+
## Quick Start
|
|
14
|
+
|
|
15
|
+
Use it directly in a page or layout:
|
|
16
|
+
|
|
17
|
+
```astro
|
|
18
|
+
---
|
|
19
|
+
import { AstroSeo } from "@lexingtonthemes/seo";
|
|
20
|
+
---
|
|
21
|
+
|
|
22
|
+
<html lang="en">
|
|
23
|
+
<head>
|
|
24
|
+
<AstroSeo
|
|
25
|
+
title="Lexington Theme - Home"
|
|
26
|
+
description="Production-ready Astro themes for freelancers and businesses."
|
|
27
|
+
canonical="https://example.com/"
|
|
28
|
+
/>
|
|
29
|
+
</head>
|
|
30
|
+
<body>
|
|
31
|
+
<slot />
|
|
32
|
+
</body>
|
|
33
|
+
</html>
|
|
34
|
+
```
|
|
35
|
+
|
|
36
|
+
## Common Examples
|
|
37
|
+
|
|
38
|
+
### Basic page SEO
|
|
39
|
+
|
|
40
|
+
```astro
|
|
41
|
+
---
|
|
42
|
+
import { AstroSeo } from "@lexingtonthemes/seo";
|
|
43
|
+
---
|
|
44
|
+
|
|
45
|
+
<AstroSeo
|
|
46
|
+
title="About"
|
|
47
|
+
description="Learn more about our team and services."
|
|
48
|
+
canonical="https://example.com/about"
|
|
49
|
+
/>
|
|
50
|
+
```
|
|
51
|
+
|
|
52
|
+
### Open Graph + Twitter
|
|
53
|
+
|
|
54
|
+
```astro
|
|
55
|
+
---
|
|
56
|
+
import { AstroSeo } from "@lexingtonthemes/seo";
|
|
57
|
+
---
|
|
58
|
+
|
|
59
|
+
<AstroSeo
|
|
60
|
+
title="Astro Landing Page Kit"
|
|
61
|
+
description="Fast, modern landing pages built with Astro."
|
|
62
|
+
canonical="https://example.com/templates/landing-kit"
|
|
63
|
+
openGraph={{
|
|
64
|
+
url: "https://example.com/templates/landing-kit",
|
|
65
|
+
title: "Astro Landing Page Kit",
|
|
66
|
+
description: "Fast, modern landing pages built with Astro.",
|
|
67
|
+
site_name: "Lexington Themes",
|
|
68
|
+
images: [
|
|
69
|
+
{
|
|
70
|
+
url: "https://example.com/og/landing-kit.jpg",
|
|
71
|
+
width: 1200,
|
|
72
|
+
height: 630,
|
|
73
|
+
alt: "Landing Page Kit Preview",
|
|
74
|
+
},
|
|
75
|
+
],
|
|
76
|
+
}}
|
|
77
|
+
twitter={{
|
|
78
|
+
cardType: "summary_large_image",
|
|
79
|
+
site: "@lexingtonthemes",
|
|
80
|
+
handle: "@lexingtonthemes",
|
|
81
|
+
}}
|
|
82
|
+
/>
|
|
83
|
+
```
|
|
84
|
+
|
|
85
|
+
### Noindex pages
|
|
86
|
+
|
|
87
|
+
```astro
|
|
88
|
+
---
|
|
89
|
+
import { AstroSeo } from "@lexingtonthemes/seo";
|
|
90
|
+
---
|
|
91
|
+
|
|
92
|
+
<AstroSeo
|
|
93
|
+
title="Internal Preview"
|
|
94
|
+
description="Internal preview page."
|
|
95
|
+
noindex={true}
|
|
96
|
+
nofollow={true}
|
|
97
|
+
/>
|
|
98
|
+
```
|
|
99
|
+
|
|
100
|
+
### Language alternates
|
|
101
|
+
|
|
102
|
+
```astro
|
|
103
|
+
---
|
|
104
|
+
import { AstroSeo } from "@lexingtonthemes/seo";
|
|
105
|
+
---
|
|
106
|
+
|
|
107
|
+
<AstroSeo
|
|
108
|
+
title="Docs"
|
|
109
|
+
description="Documentation page."
|
|
110
|
+
canonical="https://example.com/docs"
|
|
111
|
+
languageAlternates={[
|
|
112
|
+
{ hreflang: "en", href: "https://example.com/docs" },
|
|
113
|
+
{ hreflang: "sv", href: "https://example.com/sv/docs" },
|
|
114
|
+
]}
|
|
115
|
+
/>
|
|
116
|
+
```
|
|
117
|
+
|
|
118
|
+
### Extra meta/link tags
|
|
119
|
+
|
|
120
|
+
```astro
|
|
121
|
+
---
|
|
122
|
+
import { AstroSeo } from "@lexingtonthemes/seo";
|
|
123
|
+
---
|
|
124
|
+
|
|
125
|
+
<AstroSeo
|
|
126
|
+
title="PWA Page"
|
|
127
|
+
description="PWA-enabled page."
|
|
128
|
+
additionalMetaTags={[
|
|
129
|
+
{ name: "theme-color", content: "#0f172a" },
|
|
130
|
+
{ property: "og:locale", content: "en_US" },
|
|
131
|
+
]}
|
|
132
|
+
additionalLinkTags={[
|
|
133
|
+
{ rel: "icon", href: "/favicon-32x32.png", sizes: "32x32" },
|
|
134
|
+
{ rel: "manifest", href: "/site.webmanifest" },
|
|
135
|
+
]}
|
|
136
|
+
/>
|
|
137
|
+
```
|
|
138
|
+
|
|
139
|
+
## Migrating from `@astrolib/seo`
|
|
140
|
+
|
|
141
|
+
If your existing themes already use `AstroSeo`, only the import path changes:
|
|
142
|
+
|
|
143
|
+
```astro
|
|
144
|
+
---
|
|
145
|
+
import { AstroSeo } from "@astrolib/seo";
|
|
146
|
+
import { AstroSeo } from "@lexingtonthemes/seo";
|
|
147
|
+
---
|
|
148
|
+
```
|
|
149
|
+
|
|
150
|
+
The prop shape is intentionally compatible for easy migration.
|
|
151
|
+
|
|
152
|
+
## API
|
|
153
|
+
|
|
154
|
+
Main props include:
|
|
155
|
+
|
|
156
|
+
- `title`, `description`, `canonical`
|
|
157
|
+
- `openGraph`, `twitter`, `facebook`
|
|
158
|
+
- `noindex`, `nofollow`, `robotsProps`
|
|
159
|
+
- `languageAlternates`, `mobileAlternate`
|
|
160
|
+
- `additionalMetaTags`, `additionalLinkTags`
|
|
161
|
+
|
|
162
|
+
For full types, see `src/types.ts`.
|
|
163
|
+
|
|
164
|
+
## Capabilities (What You Can Output)
|
|
165
|
+
|
|
166
|
+
### Standard SEO
|
|
167
|
+
|
|
168
|
+
- Page title and optional title template
|
|
169
|
+
- Meta description
|
|
170
|
+
- Canonical URL
|
|
171
|
+
- Robots directives (`noindex`, `nofollow`)
|
|
172
|
+
- Advanced robots directives via `robotsProps`:
|
|
173
|
+
- `nosnippet`
|
|
174
|
+
- `maxSnippet`
|
|
175
|
+
- `maxImagePreview`
|
|
176
|
+
- `maxVideoPreview`
|
|
177
|
+
- `noarchive`
|
|
178
|
+
- `unavailableAfter`
|
|
179
|
+
- `noimageindex`
|
|
180
|
+
- `notranslate`
|
|
181
|
+
|
|
182
|
+
### Open Graph
|
|
183
|
+
|
|
184
|
+
- Core OG tags:
|
|
185
|
+
- `og:url`
|
|
186
|
+
- `og:type`
|
|
187
|
+
- `og:title`
|
|
188
|
+
- `og:description`
|
|
189
|
+
- `og:locale`
|
|
190
|
+
- `og:site_name`
|
|
191
|
+
- OG media:
|
|
192
|
+
- images (`og:image`, width, height, alt, type, secure_url)
|
|
193
|
+
- videos (`og:video`, width, height, alt, type, secure_url)
|
|
194
|
+
- OG type-specific fields:
|
|
195
|
+
- Profile (`firstName`, `lastName`, `username`, `gender`)
|
|
196
|
+
- Article (`publishedTime`, `modifiedTime`, `expirationTime`, `authors`, `section`, `tags`)
|
|
197
|
+
- Book (`authors`, `isbn`, `releaseDate`, `tags`)
|
|
198
|
+
- Video (`actors`, `directors`, `writers`, `duration`, `releaseDate`, `tags`, `series`)
|
|
199
|
+
|
|
200
|
+
### Twitter Cards
|
|
201
|
+
|
|
202
|
+
- `twitter:card`
|
|
203
|
+
- `twitter:site`
|
|
204
|
+
- `twitter:creator`
|
|
205
|
+
|
|
206
|
+
### Facebook
|
|
207
|
+
|
|
208
|
+
- `fb:app_id`
|
|
209
|
+
|
|
210
|
+
### Alternate URLs / Internationalization
|
|
211
|
+
|
|
212
|
+
- Mobile alternate (`media`, `href`)
|
|
213
|
+
- Language alternates (`hreflang`, `href`)
|
|
214
|
+
|
|
215
|
+
### Custom Meta and Link Tags
|
|
216
|
+
|
|
217
|
+
- Add custom HTML5 / RDFa / HTTP-Equiv meta tags via `additionalMetaTags`
|
|
218
|
+
- Add custom link tags (icon, manifest, preconnect, alternate, etc.) via `additionalLinkTags`
|
|
219
|
+
|
|
220
|
+
## Development
|
|
221
|
+
|
|
222
|
+
```bash
|
|
223
|
+
npm install
|
|
224
|
+
npm test
|
|
225
|
+
```
|
package/index.ts
ADDED
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
// Do not write code directly here, instead use the `src` folder!
|
|
2
|
+
// Then, use this file to export everything you want your user to access.
|
|
3
|
+
|
|
4
|
+
export { default as AstroSeo } from "./src/AstroSeo.astro";
|
|
5
|
+
export * from "./src/AstroSeo.astro";
|
|
6
|
+
|
|
7
|
+
export * from './src/types';
|
package/package.json
ADDED
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@lexingtonthemes/seo",
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"description": "SEO component for Astro projects",
|
|
5
|
+
"homepage": "https://github.com/Lexington-Themes/lexington-seo",
|
|
6
|
+
"bugs": {
|
|
7
|
+
"url": "https://github.com/Lexington-Themes/lexington-seo/issues"
|
|
8
|
+
},
|
|
9
|
+
"repository": {
|
|
10
|
+
"type": "git",
|
|
11
|
+
"url": "https://github.com/Lexington-Themes/lexington-seo.git"
|
|
12
|
+
},
|
|
13
|
+
"author": {
|
|
14
|
+
"name": "Michael Andreuzza",
|
|
15
|
+
"url": "https://github.com/michael-andreuzza"
|
|
16
|
+
},
|
|
17
|
+
"license": "MIT",
|
|
18
|
+
"type": "module",
|
|
19
|
+
"main": "index.ts",
|
|
20
|
+
"types": "src/types.ts",
|
|
21
|
+
"publishConfig": {
|
|
22
|
+
"access": "public"
|
|
23
|
+
},
|
|
24
|
+
"exports": {
|
|
25
|
+
".": "./index.ts",
|
|
26
|
+
"./types": "./src/types.ts",
|
|
27
|
+
"./package.json": "./package.json"
|
|
28
|
+
},
|
|
29
|
+
"files": [
|
|
30
|
+
"src",
|
|
31
|
+
"index.ts"
|
|
32
|
+
],
|
|
33
|
+
"keywords": [
|
|
34
|
+
"astro-component",
|
|
35
|
+
"withastro",
|
|
36
|
+
"astro",
|
|
37
|
+
"lexington",
|
|
38
|
+
"seo",
|
|
39
|
+
"astro-seo",
|
|
40
|
+
"astro-integration"
|
|
41
|
+
],
|
|
42
|
+
"scripts": {
|
|
43
|
+
"test": "jest"
|
|
44
|
+
},
|
|
45
|
+
"devDependencies": {
|
|
46
|
+
"@types/html-escaper": "^3.0.0",
|
|
47
|
+
"@types/jest": "^29.5.4",
|
|
48
|
+
"astro": "^1.2.1 || ^2.0.0 || ^3.0.0-beta.0 || ^3.0.0 || ^4.0.0 || ^5.0.0 || ^6.0.0",
|
|
49
|
+
"html-escaper": "^3.0.3",
|
|
50
|
+
"html-validate": "^8.18.2",
|
|
51
|
+
"jest": "^29.6.3",
|
|
52
|
+
"ts-jest": "^29.1.1",
|
|
53
|
+
"typescript": "^5.1.6"
|
|
54
|
+
},
|
|
55
|
+
"peerDependencies": {
|
|
56
|
+
"astro": "^1.2.1 || ^2.0.0 || ^3.0.0-beta.0 || ^3.0.0 || ^4.0.0 || ^5.0.0 || ^6.0.0"
|
|
57
|
+
}
|
|
58
|
+
}
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
---
|
|
2
|
+
import type { AstroSeoProps } from "./types";
|
|
3
|
+
import { buildTags } from "./utils/buildTags";
|
|
4
|
+
|
|
5
|
+
export interface Props extends AstroSeoProps {}
|
|
6
|
+
|
|
7
|
+
const {
|
|
8
|
+
title,
|
|
9
|
+
titleTemplate,
|
|
10
|
+
noindex,
|
|
11
|
+
nofollow,
|
|
12
|
+
robotsProps,
|
|
13
|
+
description,
|
|
14
|
+
canonical,
|
|
15
|
+
mobileAlternate,
|
|
16
|
+
languageAlternates,
|
|
17
|
+
openGraph,
|
|
18
|
+
facebook,
|
|
19
|
+
twitter,
|
|
20
|
+
additionalMetaTags,
|
|
21
|
+
additionalLinkTags,
|
|
22
|
+
} = Astro.props;
|
|
23
|
+
---
|
|
24
|
+
|
|
25
|
+
<Fragment
|
|
26
|
+
set:html={buildTags({
|
|
27
|
+
title,
|
|
28
|
+
titleTemplate,
|
|
29
|
+
noindex,
|
|
30
|
+
nofollow,
|
|
31
|
+
robotsProps,
|
|
32
|
+
description,
|
|
33
|
+
canonical,
|
|
34
|
+
mobileAlternate,
|
|
35
|
+
languageAlternates,
|
|
36
|
+
openGraph,
|
|
37
|
+
facebook,
|
|
38
|
+
twitter,
|
|
39
|
+
additionalMetaTags,
|
|
40
|
+
additionalLinkTags,
|
|
41
|
+
})}
|
|
42
|
+
/>
|