diff options
Diffstat (limited to 'src/utils')
| -rw-r--r-- | src/utils/schemas/blogPostSchema.ts | 49 | ||||
| -rw-r--r-- | src/utils/schemas/blogSchema.ts | 46 | ||||
| -rw-r--r-- | src/utils/schemas/breadcrumbSchema.ts | 21 | ||||
| -rw-r--r-- | src/utils/schemas/ids.ts | 3 | ||||
| -rw-r--r-- | src/utils/schemas/pageSchema.ts | 43 | ||||
| -rw-r--r-- | src/utils/schemas/personSchema.ts | 17 | ||||
| -rw-r--r-- | src/utils/schemas/websiteSchema.ts | 23 |
7 files changed, 145 insertions, 57 deletions
diff --git a/src/utils/schemas/blogPostSchema.ts b/src/utils/schemas/blogPostSchema.ts index 87e1bf2..76c6a6f 100644 --- a/src/utils/schemas/blogPostSchema.ts +++ b/src/utils/schemas/blogPostSchema.ts @@ -1,5 +1,5 @@ -import type { WithContext, BlogPosting } from "schema-dts"; -import { config } from "../../config"; +import type { BlogPosting } from "schema-dts"; +import { personId, websiteId } from "./ids"; export type BlogPostSchemaParams = { readonly dateModified: string; @@ -13,25 +13,26 @@ export type BlogPostSchemaParams = { readonly title: string; }; -export default ({ siteUrl, slug, title, description, preview, datePublished, dateModified, lang, isBasedOn }: BlogPostSchemaParams): WithContext<BlogPosting> => ({ - "@context": "https://schema.org", - "@type": "BlogPosting", - "url": new URL(`/blog/${slug}`, siteUrl).toString(), - "headline": title, - "description": description, - "image": new URL(preview, siteUrl).toString(), - "datePublished": datePublished, - "dateModified": dateModified, - "inLanguage": lang, - "author": { - "@type": "Person", - "name": config.author.name, - "url": config.author.url, - "sameAs": config.author.sameAs, - }, - "mainEntityOfPage": { - "@type": "WebPage", - "@id": new URL(`/blog/${slug}`, siteUrl).toString(), - }, - ...(isBasedOn && { isBasedOn: isBasedOn }), -}); +export default ({ siteUrl, slug, title, description, preview, datePublished, dateModified, lang, isBasedOn }: BlogPostSchemaParams): BlogPosting => { + const url = new URL(`/blog/${slug}`, siteUrl).toString(); + + return { + "@type": "BlogPosting", + "@id": url, + "url": url, + "headline": title, + "description": description, + "image": new URL(preview, siteUrl).toString(), + "datePublished": datePublished, + "dateModified": dateModified, + "inLanguage": lang, + "author": { "@id": personId(siteUrl) }, + "publisher": { "@id": personId(siteUrl) }, + "isPartOf": { "@id": websiteId(siteUrl) }, + "mainEntityOfPage": { + "@type": "WebPage", + "@id": url, + }, + ...(isBasedOn && { isBasedOn: isBasedOn }), + }; +}; diff --git a/src/utils/schemas/blogSchema.ts b/src/utils/schemas/blogSchema.ts index 196f037..ff3ce65 100644 --- a/src/utils/schemas/blogSchema.ts +++ b/src/utils/schemas/blogSchema.ts @@ -1,26 +1,36 @@ -import type { WithContext, CollectionPage } from "schema-dts"; +import type { CollectionPage } from "schema-dts"; import type { CollectionEntry } from "astro:content"; +import { websiteId } from "./ids"; export type BlogSchemaParams = { + readonly description: string; + readonly lang: string; readonly posts: CollectionEntry<"blog">[]; readonly siteUrl: string; readonly title: string; }; -export default ({ siteUrl, title, posts }: BlogSchemaParams): WithContext<CollectionPage> => ({ - "@context": "https://schema.org", - "@type": "CollectionPage", - "url": new URL("/blog/", siteUrl).toString(), - "name": title, - "mainEntity": { - "@type": "ItemList", - "itemListOrder": "https://schema.org/ItemListOrderDescending", - "numberOfItems": posts.length, - "itemListElement": posts.map((post, index) => ({ - "@type": "ListItem", - "position": index + 1, - "url": new URL(`/blog/${post.id}`, siteUrl).toString(), - "name": post.data.title, - })), - }, -}); +export default ({ siteUrl, title, description, lang, posts }: BlogSchemaParams): CollectionPage => { + const url = new URL("/blog/", siteUrl).toString(); + + return { + "@type": "CollectionPage", + "@id": url, + "url": url, + "name": title, + "description": description, + "inLanguage": lang, + "isPartOf": { "@id": websiteId(siteUrl) }, + "mainEntity": { + "@type": "ItemList", + "itemListOrder": "https://schema.org/ItemListOrderDescending", + "numberOfItems": posts.length, + "itemListElement": posts.map((post, index) => ({ + "@type": "ListItem", + "position": index + 1, + "url": new URL(`/blog/${post.id}`, siteUrl).toString(), + "name": post.data.title, + })), + }, + }; +}; diff --git a/src/utils/schemas/breadcrumbSchema.ts b/src/utils/schemas/breadcrumbSchema.ts new file mode 100644 index 0000000..e1a1ea3 --- /dev/null +++ b/src/utils/schemas/breadcrumbSchema.ts @@ -0,0 +1,21 @@ +import type { BreadcrumbList } from "schema-dts"; + +export type BreadcrumbItem = { + readonly name: string; + readonly url: string; +}; + +export type BreadcrumbSchemaParams = { + readonly items: BreadcrumbItem[]; + readonly siteUrl: string; +}; + +export default ({ items, siteUrl }: BreadcrumbSchemaParams): BreadcrumbList => ({ + "@type": "BreadcrumbList", + "itemListElement": items.map((item, index) => ({ + "@type": "ListItem", + "position": index + 1, + "name": item.name, + "item": new URL(item.url, siteUrl).toString(), + })), +}); diff --git a/src/utils/schemas/ids.ts b/src/utils/schemas/ids.ts new file mode 100644 index 0000000..1d7e8c5 --- /dev/null +++ b/src/utils/schemas/ids.ts @@ -0,0 +1,3 @@ +export const websiteId = (siteUrl: string): string => new URL("#website", siteUrl).toString(); + +export const personId = (siteUrl: string): string => new URL("#person", siteUrl).toString(); diff --git a/src/utils/schemas/pageSchema.ts b/src/utils/schemas/pageSchema.ts index 606488b..ba8fd86 100644 --- a/src/utils/schemas/pageSchema.ts +++ b/src/utils/schemas/pageSchema.ts @@ -1,23 +1,36 @@ -import type { WithContext, WebPage } from "schema-dts"; +import type { ProfilePage, WebPage } from "schema-dts"; +import { personId, websiteId } from "./ids"; export type WebsiteSchemaParams = { readonly description: string; + readonly lang: string; + readonly mainEntityId?: string; readonly page: string; readonly siteUrl: string; readonly title: string; - readonly lang: string; + readonly type?: "WebPage" | "ProfilePage"; }; -export default ({ siteUrl, page, title, description, lang }: WebsiteSchemaParams): WithContext<WebPage> => ({ - "@context": "https://schema.org", - "@type": "WebPage", - "@id": new URL(page, siteUrl).toString(), - "url": new URL(page, siteUrl).toString(), - "name": title, - "description": description, - "inLanguage": lang, - "mainEntity": { - "@type": "WebSite", - "@id": new URL("/", siteUrl).toString(), - }, -}); +export default ({ siteUrl, page, title, description, lang, type = "WebPage", mainEntityId }: WebsiteSchemaParams): WebPage | ProfilePage => { + const url = new URL(page, siteUrl).toString(); + + const base = { + "@type": type, + "@id": url, + "url": url, + "name": title, + "description": description, + "inLanguage": lang, + "isPartOf": { "@id": websiteId(siteUrl) }, + } as const; + + if (type === "ProfilePage") { + return { + ...base, + "@type": "ProfilePage", + "mainEntity": { "@id": mainEntityId ?? personId(siteUrl) }, + }; + } + + return base; +}; diff --git a/src/utils/schemas/personSchema.ts b/src/utils/schemas/personSchema.ts new file mode 100644 index 0000000..77e443d --- /dev/null +++ b/src/utils/schemas/personSchema.ts @@ -0,0 +1,17 @@ +import type { Person } from "schema-dts"; +import { config } from "../../config"; +import { personId } from "./ids"; + +export type PersonSchemaParams = { + readonly siteUrl: string; +}; + +export default ({ siteUrl }: PersonSchemaParams): Person => ({ + "@type": "Person", + "@id": personId(siteUrl), + "name": config.author.name, + "url": config.author.url, + "email": config.author.email, + "image": new URL(config.og.defaultPreview, siteUrl).toString(), + "sameAs": config.author.sameAs, +}); diff --git a/src/utils/schemas/websiteSchema.ts b/src/utils/schemas/websiteSchema.ts new file mode 100644 index 0000000..2f69427 --- /dev/null +++ b/src/utils/schemas/websiteSchema.ts @@ -0,0 +1,23 @@ +import type { WebSite } from "schema-dts"; +import { config } from "../../config"; +import { personId, websiteId } from "./ids"; + +export type WebsiteSchemaParams = { + readonly description: string; + readonly lang: string; + readonly name: string; + readonly siteUrl: string; +}; + +export default ({ siteUrl, name, description, lang }: WebsiteSchemaParams): WebSite => ({ + "@type": "WebSite", + "@id": websiteId(siteUrl), + "url": siteUrl, + "name": name, + "description": description, + "inLanguage": lang, + "publisher": { "@id": personId(siteUrl) }, + "author": { "@id": personId(siteUrl) }, + "copyrightHolder": { "@id": personId(siteUrl) }, + "sameAs": config.author.sameAs, +}); |
