159 lines
4.3 KiB
Plaintext
159 lines
4.3 KiB
Plaintext
---
|
|
import OpenGraphArticleTags from "./components/OpenGraphArticleTags.astro";
|
|
import OpenGraphBasicTags from "./components/OpenGraphBasicTags.astro";
|
|
import OpenGraphImageTags from "./components/OpenGraphImageTags.astro";
|
|
import OpenGraphOptionalTags from "./components/OpenGraphOptionalTags.astro";
|
|
import ExtendedTags from "./components/ExtendedTags.astro";
|
|
import TwitterTags from "./components/TwitterTags.astro";
|
|
import LanguageAlternatesTags from "./components/LanguageAlternatesTags.astro";
|
|
|
|
export type TwitterCardType = "summary" | "summary_large_image" | "app" | "player";
|
|
|
|
export interface Link extends Omit<HTMLLinkElement, 'sizes'> {
|
|
prefetch: boolean;
|
|
crossorigin: string;
|
|
sizes: string;
|
|
}
|
|
|
|
export interface Meta extends HTMLMetaElement {
|
|
property: string;
|
|
}
|
|
|
|
export interface Props {
|
|
title?: string;
|
|
titleTemplate?: string;
|
|
titleDefault?: string;
|
|
charset?: string;
|
|
description?: string;
|
|
canonical?: URL | string;
|
|
nofollow?: boolean;
|
|
noindex?: boolean;
|
|
languageAlternates?: {
|
|
href: URL | string;
|
|
hrefLang: string;
|
|
}[];
|
|
openGraph?: {
|
|
basic: {
|
|
title: string;
|
|
type: string;
|
|
image: string;
|
|
url?: URL | string;
|
|
};
|
|
optional?: {
|
|
audio?: string;
|
|
description?: string;
|
|
determiner?: string;
|
|
locale?: string;
|
|
localeAlternate?: string[];
|
|
siteName?: string;
|
|
video?: string;
|
|
};
|
|
image?: {
|
|
url?: URL | string;
|
|
secureUrl?: URL | string;
|
|
type?: string;
|
|
width?: number;
|
|
height?: number;
|
|
alt?: string;
|
|
};
|
|
article?: {
|
|
publishedTime?: string;
|
|
modifiedTime?: string;
|
|
expirationTime?: string;
|
|
authors?: string[];
|
|
section?: string;
|
|
tags?: string[];
|
|
};
|
|
};
|
|
twitter?: {
|
|
card?: TwitterCardType;
|
|
site?: string;
|
|
creator?: string;
|
|
title?: string;
|
|
description?: string;
|
|
image?: URL | string;
|
|
imageAlt?: string;
|
|
};
|
|
extend?: {
|
|
link?: Partial<Link>[];
|
|
meta?: Partial<Meta>[];
|
|
};
|
|
surpressWarnings?: boolean;
|
|
}
|
|
|
|
Astro.props.surpressWarnings = true;
|
|
|
|
function validateProps(props: Props) {
|
|
if (props.openGraph) {
|
|
if (
|
|
!props.openGraph.basic ||
|
|
(props.openGraph.basic.title ?? undefined) == undefined ||
|
|
(props.openGraph.basic.type ?? undefined) == undefined ||
|
|
(props.openGraph.basic.image ?? undefined) == undefined
|
|
) {
|
|
throw new Error(
|
|
"If you pass the openGraph prop, you have to at least define the title, type, and image basic properties!"
|
|
);
|
|
}
|
|
}
|
|
|
|
if (props.title && props.openGraph?.basic.title) {
|
|
if (props.title == props.openGraph.basic.title && !props.surpressWarnings) {
|
|
console.warn(
|
|
"WARNING(astro-seo): You passed the same value to `title` and `openGraph.optional.title`. This is most likely not what you want. See docs for more."
|
|
);
|
|
}
|
|
}
|
|
|
|
if (
|
|
props.openGraph?.basic?.image &&
|
|
!props.openGraph?.image?.alt &&
|
|
!props.surpressWarnings
|
|
) {
|
|
console.warn(
|
|
"WARNING(astro-seo): You defined `openGraph.basic.image`, but didn't define `openGraph.image.alt`. This is strongly discouraged.'"
|
|
);
|
|
}
|
|
}
|
|
|
|
validateProps(Astro.props);
|
|
|
|
let updatedTitle = "";
|
|
|
|
if (Astro.props.title) {
|
|
updatedTitle = Astro.props.title;
|
|
if (Astro.props.titleTemplate) {
|
|
updatedTitle = Astro.props.titleTemplate.replace(/%s/g, updatedTitle);
|
|
}
|
|
} else if (Astro.props.titleDefault) {
|
|
updatedTitle = Astro.props.titleDefault;
|
|
}
|
|
---
|
|
|
|
{updatedTitle ? <title set:html={updatedTitle} /> : null}
|
|
|
|
{Astro.props.charset ? <meta charset={Astro.props.charset} /> : null}
|
|
|
|
<link rel="canonical" href={Astro.props.canonical || Astro.url.href} />
|
|
|
|
{
|
|
Astro.props.description ? (
|
|
<meta name="description" content={Astro.props.description} />
|
|
) : null
|
|
}
|
|
|
|
<meta
|
|
name="robots"
|
|
content={`${Astro.props.noindex ? "noindex" : "index"}, ${
|
|
Astro.props.nofollow ? "nofollow" : "follow"
|
|
}`}
|
|
/>
|
|
|
|
{Astro.props.openGraph && <OpenGraphBasicTags {...Astro.props} />}
|
|
{Astro.props.openGraph?.optional && <OpenGraphOptionalTags {...Astro.props} />}
|
|
{Astro.props.openGraph?.image && <OpenGraphImageTags {...Astro.props} />}
|
|
{Astro.props.openGraph?.article && <OpenGraphArticleTags {...Astro.props} />}
|
|
{Astro.props.twitter && <TwitterTags {...Astro.props} />}
|
|
{Astro.props.extend && <ExtendedTags {...Astro.props} />}
|
|
{Astro.props.languageAlternates && <LanguageAlternatesTags {...Astro.props} />}
|