@vakwerk/seo 0.1.2 → 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/dist/index.d.ts CHANGED
@@ -1,3 +1,4 @@
1
1
  export type { SEOProps } from './types.js';
2
2
  export { resolveCanonicalUrl, resolveImageUrl, resolveTitle } from './url.js';
3
+ export { faqPage, breadcrumbList, webSite, itemList, howTo, article, organization, } from './schemas.js';
3
4
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,YAAY,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAC;AAC3C,OAAO,EAAE,mBAAmB,EAAE,eAAe,EAAE,YAAY,EAAE,MAAM,UAAU,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,YAAY,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAC;AAC3C,OAAO,EAAE,mBAAmB,EAAE,eAAe,EAAE,YAAY,EAAE,MAAM,UAAU,CAAC;AAC9E,OAAO,EACN,OAAO,EACP,cAAc,EACd,OAAO,EACP,QAAQ,EACR,KAAK,EACL,OAAO,EACP,YAAY,GACZ,MAAM,cAAc,CAAC"}
package/dist/index.js CHANGED
@@ -1,2 +1,3 @@
1
1
  export { resolveCanonicalUrl, resolveImageUrl, resolveTitle } from './url.js';
2
+ export { faqPage, breadcrumbList, webSite, itemList, howTo, article, organization, } from './schemas.js';
2
3
  //# sourceMappingURL=index.js.map
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,mBAAmB,EAAE,eAAe,EAAE,YAAY,EAAE,MAAM,UAAU,CAAC"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,mBAAmB,EAAE,eAAe,EAAE,YAAY,EAAE,MAAM,UAAU,CAAC;AAC9E,OAAO,EACN,OAAO,EACP,cAAc,EACd,OAAO,EACP,QAAQ,EACR,KAAK,EACL,OAAO,EACP,YAAY,GACZ,MAAM,cAAc,CAAC"}
@@ -0,0 +1,100 @@
1
+ export declare function faqPage(items: {
2
+ question: string;
3
+ answer: string;
4
+ }[]): {
5
+ '@context': string;
6
+ '@type': "FAQPage";
7
+ mainEntity: {
8
+ '@type': "Question";
9
+ name: string;
10
+ acceptedAnswer: {
11
+ '@type': "Answer";
12
+ text: string;
13
+ };
14
+ }[];
15
+ };
16
+ export declare function breadcrumbList(items: {
17
+ name: string;
18
+ url: string;
19
+ }[]): {
20
+ '@context': string;
21
+ '@type': "BreadcrumbList";
22
+ itemListElement: {
23
+ '@type': "ListItem";
24
+ position: number;
25
+ name: string;
26
+ item: string;
27
+ }[];
28
+ };
29
+ export declare function webSite(name: string, url: string): {
30
+ '@context': string;
31
+ '@type': "WebSite";
32
+ name: string;
33
+ url: string;
34
+ };
35
+ export declare function itemList(name: string, items: {
36
+ name: string;
37
+ url: string;
38
+ }[]): {
39
+ '@context': string;
40
+ '@type': "ItemList";
41
+ name: string;
42
+ itemListElement: {
43
+ '@type': "ListItem";
44
+ position: number;
45
+ name: string;
46
+ item: string;
47
+ }[];
48
+ };
49
+ export declare function howTo(name: string, steps: string[], opts?: {
50
+ description?: string;
51
+ }): {
52
+ step: {
53
+ '@type': "HowToStep";
54
+ position: number;
55
+ text: string;
56
+ }[];
57
+ description?: string | undefined;
58
+ '@context': string;
59
+ '@type': "HowTo";
60
+ name: string;
61
+ };
62
+ export declare function article(headline: string, opts: {
63
+ author: {
64
+ name: string;
65
+ url?: string;
66
+ };
67
+ datePublished: string;
68
+ dateModified?: string;
69
+ image?: string | string[];
70
+ description?: string;
71
+ url?: string;
72
+ }): {
73
+ url?: string | undefined;
74
+ description?: string | undefined;
75
+ image?: string | string[] | undefined;
76
+ dateModified?: string | undefined;
77
+ '@context': string;
78
+ '@type': "Article";
79
+ headline: string;
80
+ author: {
81
+ url?: string | undefined;
82
+ '@type': "Person";
83
+ name: string;
84
+ };
85
+ datePublished: string;
86
+ };
87
+ export declare function organization(name: string, url: string, opts?: {
88
+ logo?: string;
89
+ description?: string;
90
+ sameAs?: string[];
91
+ }): {
92
+ sameAs?: string[] | undefined;
93
+ description?: string | undefined;
94
+ logo?: string | undefined;
95
+ '@context': string;
96
+ '@type': "Organization";
97
+ name: string;
98
+ url: string;
99
+ };
100
+ //# sourceMappingURL=schemas.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"schemas.d.ts","sourceRoot":"","sources":["../src/schemas.ts"],"names":[],"mappings":"AAEA,wBAAgB,OAAO,CAAC,KAAK,EAAE;IAAE,QAAQ,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,MAAM,CAAA;CAAE,EAAE;;;;;;;;;;;EAapE;AAED,wBAAgB,cAAc,CAAC,KAAK,EAAE;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,GAAG,EAAE,MAAM,CAAA;CAAE,EAAE;;;;;;;;;EAWpE;AAED,wBAAgB,OAAO,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM;;;;;EAOhD;AAED,wBAAgB,QAAQ,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,GAAG,EAAE,MAAM,CAAA;CAAE,EAAE;;;;;;;;;;EAY5E;AAED,wBAAgB,KAAK,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,EAAE,IAAI,CAAC,EAAE;IAAE,WAAW,CAAC,EAAE,MAAM,CAAA;CAAE;;;;;;;;;;EAYnF;AAED,wBAAgB,OAAO,CACrB,QAAQ,EAAE,MAAM,EAChB,IAAI,EAAE;IACJ,MAAM,EAAE;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,GAAG,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC;IACvC,aAAa,EAAE,MAAM,CAAC;IACtB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,KAAK,CAAC,EAAE,MAAM,GAAG,MAAM,EAAE,CAAC;IAC1B,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,GAAG,CAAC,EAAE,MAAM,CAAC;CACd;;;;;;;;;;;;;;EAiBF;AAED,wBAAgB,YAAY,CAC1B,IAAI,EAAE,MAAM,EACZ,GAAG,EAAE,MAAM,EACX,IAAI,CAAC,EAAE;IAAE,IAAI,CAAC,EAAE,MAAM,CAAC;IAAC,WAAW,CAAC,EAAE,MAAM,CAAC;IAAC,MAAM,CAAC,EAAE,MAAM,EAAE,CAAA;CAAE;;;;;;;;EAWlE"}
@@ -0,0 +1,90 @@
1
+ const CONTEXT = 'https://schema.org';
2
+ export function faqPage(items) {
3
+ return {
4
+ '@context': CONTEXT,
5
+ '@type': 'FAQPage',
6
+ mainEntity: items.map((item) => ({
7
+ '@type': 'Question',
8
+ name: item.question,
9
+ acceptedAnswer: {
10
+ '@type': 'Answer',
11
+ text: item.answer,
12
+ },
13
+ })),
14
+ };
15
+ }
16
+ export function breadcrumbList(items) {
17
+ return {
18
+ '@context': CONTEXT,
19
+ '@type': 'BreadcrumbList',
20
+ itemListElement: items.map((item, index) => ({
21
+ '@type': 'ListItem',
22
+ position: index + 1,
23
+ name: item.name,
24
+ item: item.url,
25
+ })),
26
+ };
27
+ }
28
+ export function webSite(name, url) {
29
+ return {
30
+ '@context': CONTEXT,
31
+ '@type': 'WebSite',
32
+ name,
33
+ url,
34
+ };
35
+ }
36
+ export function itemList(name, items) {
37
+ return {
38
+ '@context': CONTEXT,
39
+ '@type': 'ItemList',
40
+ name,
41
+ itemListElement: items.map((item, index) => ({
42
+ '@type': 'ListItem',
43
+ position: index + 1,
44
+ name: item.name,
45
+ item: item.url,
46
+ })),
47
+ };
48
+ }
49
+ export function howTo(name, steps, opts) {
50
+ return {
51
+ '@context': CONTEXT,
52
+ '@type': 'HowTo',
53
+ name,
54
+ ...(opts?.description && { description: opts.description }),
55
+ step: steps.map((text, index) => ({
56
+ '@type': 'HowToStep',
57
+ position: index + 1,
58
+ text,
59
+ })),
60
+ };
61
+ }
62
+ export function article(headline, opts) {
63
+ return {
64
+ '@context': CONTEXT,
65
+ '@type': 'Article',
66
+ headline,
67
+ author: {
68
+ '@type': 'Person',
69
+ name: opts.author.name,
70
+ ...(opts.author.url && { url: opts.author.url }),
71
+ },
72
+ datePublished: opts.datePublished,
73
+ ...(opts.dateModified && { dateModified: opts.dateModified }),
74
+ ...(opts.image && { image: opts.image }),
75
+ ...(opts.description && { description: opts.description }),
76
+ ...(opts.url && { url: opts.url }),
77
+ };
78
+ }
79
+ export function organization(name, url, opts) {
80
+ return {
81
+ '@context': CONTEXT,
82
+ '@type': 'Organization',
83
+ name,
84
+ url,
85
+ ...(opts?.logo && { logo: opts.logo }),
86
+ ...(opts?.description && { description: opts.description }),
87
+ ...(opts?.sameAs && { sameAs: opts.sameAs }),
88
+ };
89
+ }
90
+ //# sourceMappingURL=schemas.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"schemas.js","sourceRoot":"","sources":["../src/schemas.ts"],"names":[],"mappings":"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"}
package/dist/types.d.ts CHANGED
@@ -7,11 +7,11 @@ export interface SEOProps {
7
7
  type?: 'website' | 'article';
8
8
  image?: {
9
9
  src: string;
10
- alt?: string;
10
+ alt: string;
11
11
  };
12
12
  locale?: string;
13
13
  noindex?: boolean;
14
- schemas?: object[];
14
+ schemas?: Record<string, unknown>[];
15
15
  twitterCard?: 'summary' | 'summary_large_image';
16
16
  }
17
17
  //# sourceMappingURL=types.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA,MAAM,WAAW,QAAQ;IACvB,KAAK,EAAE,MAAM,CAAC;IACd,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,WAAW,EAAE,MAAM,CAAC;IACpB,QAAQ,EAAE,MAAM,CAAC;IACjB,YAAY,CAAC,EAAE,MAAM,GAAG,GAAG,CAAC;IAC5B,IAAI,CAAC,EAAE,SAAS,GAAG,SAAS,CAAC;IAC7B,KAAK,CAAC,EAAE;QAAE,GAAG,EAAE,MAAM,CAAC;QAAC,GAAG,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC;IACtC,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,OAAO,CAAC,EAAE,MAAM,EAAE,CAAC;IACnB,WAAW,CAAC,EAAE,SAAS,GAAG,qBAAqB,CAAC;CACjD"}
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA,MAAM,WAAW,QAAQ;IACvB,KAAK,EAAE,MAAM,CAAC;IACd,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,WAAW,EAAE,MAAM,CAAC;IACpB,QAAQ,EAAE,MAAM,CAAC;IACjB,YAAY,CAAC,EAAE,MAAM,GAAG,GAAG,CAAC;IAC5B,IAAI,CAAC,EAAE,SAAS,GAAG,SAAS,CAAC;IAC7B,KAAK,CAAC,EAAE;QAAE,GAAG,EAAE,MAAM,CAAC;QAAC,GAAG,EAAE,MAAM,CAAA;KAAE,CAAC;IACrC,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAAE,CAAC;IACpC,WAAW,CAAC,EAAE,SAAS,GAAG,qBAAqB,CAAC;CACjD"}
package/dist/url.js CHANGED
@@ -18,7 +18,7 @@ export function resolveTitle(title, template) {
18
18
  if (!template.includes('%s')) {
19
19
  throw new Error('@vakwerk/seo: titleTemplate must contain a %s placeholder');
20
20
  }
21
- return template.replace('%s', title);
21
+ return template.replaceAll('%s', title);
22
22
  }
23
23
  export function resolveImageUrl(src, site) {
24
24
  if (src.startsWith('http://') || src.startsWith('https://')) {
package/dist/url.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"url.js","sourceRoot":"","sources":["../src/url.ts"],"names":[],"mappings":"AAAA,MAAM,UAAU,mBAAmB,CACjC,QAAgB,EAChB,IAAqB,EACrB,QAAuB;IAEvB,IAAI,QAAQ,YAAY,GAAG,EAAE,CAAC;QAC5B,OAAO,QAAQ,CAAC,IAAI,CAAC;IACvB,CAAC;IAED,IAAI,OAAO,QAAQ,KAAK,QAAQ,IAAI,CAAC,QAAQ,CAAC,UAAU,CAAC,SAAS,CAAC,IAAI,QAAQ,CAAC,UAAU,CAAC,UAAU,CAAC,CAAC,EAAE,CAAC;QACxG,OAAO,QAAQ,CAAC;IAClB,CAAC;IAED,MAAM,IAAI,GAAG,QAAQ,IAAI,QAAQ,CAAC;IAElC,IAAI,CAAC,IAAI,EAAE,CAAC;QACV,MAAM,IAAI,KAAK,CAAC,8EAA8E,CAAC,CAAC;IAClG,CAAC;IAED,MAAM,UAAU,GAAG,IAAI,KAAK,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC,OAAO,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC;IACjE,OAAO,IAAI,GAAG,CAAC,UAAU,EAAE,IAAI,CAAC,CAAC,IAAI,CAAC;AACxC,CAAC;AAED,MAAM,UAAU,YAAY,CAAC,KAAa,EAAE,QAAiB;IAC3D,IAAI,CAAC,QAAQ;QAAE,OAAO,KAAK,CAAC;IAC5B,IAAI,CAAC,QAAQ,CAAC,QAAQ,CAAC,IAAI,CAAC,EAAE,CAAC;QAC7B,MAAM,IAAI,KAAK,CAAC,2DAA2D,CAAC,CAAC;IAC/E,CAAC;IACD,OAAO,QAAQ,CAAC,OAAO,CAAC,IAAI,EAAE,KAAK,CAAC,CAAC;AACvC,CAAC;AAED,MAAM,UAAU,eAAe,CAC7B,GAAW,EACX,IAAqB;IAErB,IAAI,GAAG,CAAC,UAAU,CAAC,SAAS,CAAC,IAAI,GAAG,CAAC,UAAU,CAAC,UAAU,CAAC,EAAE,CAAC;QAC5D,OAAO,GAAG,CAAC;IACb,CAAC;IAED,IAAI,CAAC,IAAI,EAAE,CAAC;QACV,MAAM,IAAI,KAAK,CAAC,oEAAoE,CAAC,CAAC;IACxF,CAAC;IAED,OAAO,IAAI,GAAG,CAAC,GAAG,EAAE,IAAI,CAAC,CAAC,IAAI,CAAC;AACjC,CAAC"}
1
+ {"version":3,"file":"url.js","sourceRoot":"","sources":["../src/url.ts"],"names":[],"mappings":"AAAA,MAAM,UAAU,mBAAmB,CACjC,QAAgB,EAChB,IAAqB,EACrB,QAAuB;IAEvB,IAAI,QAAQ,YAAY,GAAG,EAAE,CAAC;QAC5B,OAAO,QAAQ,CAAC,IAAI,CAAC;IACvB,CAAC;IAED,IAAI,OAAO,QAAQ,KAAK,QAAQ,IAAI,CAAC,QAAQ,CAAC,UAAU,CAAC,SAAS,CAAC,IAAI,QAAQ,CAAC,UAAU,CAAC,UAAU,CAAC,CAAC,EAAE,CAAC;QACxG,OAAO,QAAQ,CAAC;IAClB,CAAC;IAED,MAAM,IAAI,GAAG,QAAQ,IAAI,QAAQ,CAAC;IAElC,IAAI,CAAC,IAAI,EAAE,CAAC;QACV,MAAM,IAAI,KAAK,CAAC,8EAA8E,CAAC,CAAC;IAClG,CAAC;IAED,MAAM,UAAU,GAAG,IAAI,KAAK,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC,OAAO,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC;IACjE,OAAO,IAAI,GAAG,CAAC,UAAU,EAAE,IAAI,CAAC,CAAC,IAAI,CAAC;AACxC,CAAC;AAED,MAAM,UAAU,YAAY,CAAC,KAAa,EAAE,QAAiB;IAC3D,IAAI,CAAC,QAAQ;QAAE,OAAO,KAAK,CAAC;IAC5B,IAAI,CAAC,QAAQ,CAAC,QAAQ,CAAC,IAAI,CAAC,EAAE,CAAC;QAC7B,MAAM,IAAI,KAAK,CAAC,2DAA2D,CAAC,CAAC;IAC/E,CAAC;IACD,OAAO,QAAQ,CAAC,UAAU,CAAC,IAAI,EAAE,KAAK,CAAC,CAAC;AAC1C,CAAC;AAED,MAAM,UAAU,eAAe,CAC7B,GAAW,EACX,IAAqB;IAErB,IAAI,GAAG,CAAC,UAAU,CAAC,SAAS,CAAC,IAAI,GAAG,CAAC,UAAU,CAAC,UAAU,CAAC,EAAE,CAAC;QAC5D,OAAO,GAAG,CAAC;IACb,CAAC;IAED,IAAI,CAAC,IAAI,EAAE,CAAC;QACV,MAAM,IAAI,KAAK,CAAC,oEAAoE,CAAC,CAAC;IACxF,CAAC;IAED,OAAO,IAAI,GAAG,CAAC,GAAG,EAAE,IAAI,CAAC,CAAC,IAAI,CAAC;AACjC,CAAC"}
package/package.json CHANGED
@@ -1,26 +1,28 @@
1
1
  {
2
2
  "name": "@vakwerk/seo",
3
- "version": "0.1.2",
3
+ "version": "0.2.0",
4
4
  "type": "module",
5
5
  "exports": {
6
6
  ".": {
7
7
  "types": "./dist/index.d.ts",
8
8
  "import": "./dist/index.js"
9
9
  },
10
- "./SEO.astro": "./src/SEO.astro"
10
+ "./SEO.astro": "./src/SEO.astro",
11
+ "./JsonLd.astro": "./src/JsonLd.astro"
11
12
  },
12
13
  "files": [
13
14
  "dist",
14
- "src/SEO.astro"
15
+ "src/SEO.astro",
16
+ "src/JsonLd.astro"
15
17
  ],
18
+ "peerDependencies": {
19
+ "astro": ">=5.0.0"
20
+ },
16
21
  "scripts": {
17
22
  "build": "tsc",
18
23
  "test": "vitest run",
19
24
  "test:watch": "vitest",
20
25
  "check:types": "tsc --noEmit",
21
26
  "lint": "echo 'no linter configured yet'"
22
- },
23
- "peerDependencies": {
24
- "astro": ">=5.0.0"
25
27
  }
26
- }
28
+ }
@@ -0,0 +1,12 @@
1
+ ---
2
+ interface Props {
3
+ data: Record<string, unknown> | Record<string, unknown>[];
4
+ }
5
+
6
+ const { data } = Astro.props;
7
+ const schemas = Array.isArray(data) ? data : [data];
8
+ ---
9
+
10
+ {schemas.map((schema) => (
11
+ <script type="application/ld+json" set:html={JSON.stringify(schema).replaceAll('<', '\\u003c')} />
12
+ ))}
package/src/SEO.astro CHANGED
@@ -1,6 +1,7 @@
1
1
  ---
2
2
  import type { SEOProps } from '@vakwerk/seo';
3
3
  import { resolveCanonicalUrl, resolveImageUrl, resolveTitle } from '@vakwerk/seo';
4
+ import JsonLd from './JsonLd.astro';
4
5
 
5
6
  type Props = SEOProps;
6
7
 
@@ -37,13 +38,11 @@ const robots = noindex ? 'noindex, nofollow' : 'index, follow';
37
38
  <meta property="og:locale" content={locale} />
38
39
  <meta property="og:site_name" content={siteName} />
39
40
  {resolvedImage && <meta property="og:image" content={resolvedImage} />}
40
- {resolvedImage && image?.alt && <meta property="og:image:alt" content={image.alt} />}
41
+ {resolvedImage && <meta property="og:image:alt" content={image!.alt} />}
41
42
 
42
43
  <meta name="twitter:card" content={card} />
43
44
  <meta name="twitter:title" content={title} />
44
45
  <meta name="twitter:description" content={description} />
45
46
  {resolvedImage && <meta name="twitter:image" content={resolvedImage} />}
46
47
 
47
- {schemas.map((schema) => (
48
- <script is:inline type="application/ld+json" set:html={JSON.stringify(schema).replace(/<\/script>/gi, '<\\/script>')} />
49
- ))}
48
+ {schemas.length > 0 && <JsonLd data={schemas} />}