sitegen/framework/meta/nextjs/generate/meta.tsx
chloe caruso af60d1172f i accidentally deleted the repo, but recovered it. i'll start committing
it was weird. i pressed delete on a subfolder, i think one of the
pages.off folders that i was using. and then, suddenly, nvim on windows
7 decided to delete every file in the directory. they weren't shred off
the space time continuum, but just marked deleted. i had to pay $80 to
get access to a software that could see them. bleh!

just seeing all my work, a little over a week, was pretty heart
shattering. but i remembered that long ago, a close friend said i could
call them whenever i was feeling sad. i finally took them up on that
offer. the first time i've ever called someone for emotional support.
but it's ok. i got it back. and the site framework is better than ever.

i'm gonna commit and push more often. the repo is private anyways.
2025-06-06 23:38:02 -07:00

124 lines
3 KiB
TypeScript

import React from "react";
export function Meta({
name,
property,
content,
media,
}: {
name?: string;
property?: string;
media?: string;
content: string | number | URL | null | undefined;
}): React.ReactElement | null {
if (typeof content !== "undefined" && content !== null && content !== "") {
return (
<meta
{...(name ? { name } : { property })}
{...(media ? { media } : undefined)}
content={typeof content === "string" ? content : content.toString()}
/>
);
}
return null;
}
type ExtendMetaContent = Record<
string,
undefined | string | URL | number | boolean | null | undefined
>;
type MultiMetaContent =
| (ExtendMetaContent | string | URL | number)[]
| null
| undefined;
function camelToSnake(camelCaseStr: string) {
return camelCaseStr.replace(/([A-Z])/g, function (match) {
return "_" + match.toLowerCase();
});
}
function getMetaKey(prefix: string, key: string) {
// Use `twitter:image` and `og:image` instead of `twitter:image:url` and `og:image:url`
// to be more compatible as it's a more common format
if ((prefix === "og:image" || prefix === "twitter:image") && key === "url") {
return prefix;
}
if (prefix.startsWith("og:") || prefix.startsWith("twitter:")) {
key = camelToSnake(key);
}
return prefix + ":" + key;
}
function ExtendMeta({
content,
namePrefix,
propertyPrefix,
}: {
content?: ExtendMetaContent;
namePrefix?: string;
propertyPrefix?: string;
}) {
const keyPrefix = namePrefix || propertyPrefix;
if (!content) return null;
return (
<React.Fragment>
{Object.entries(content).map(([k, v], index) => {
return typeof v === "undefined" ? null : (
<Meta
key={keyPrefix + ":" + k + "_" + index}
{...(propertyPrefix && { property: getMetaKey(propertyPrefix, k) })}
{...(namePrefix && { name: getMetaKey(namePrefix, k) })}
content={typeof v === "string" ? v : v?.toString()}
/>
);
})}
</React.Fragment>
);
}
export function MultiMeta({
propertyPrefix,
namePrefix,
contents,
}: {
propertyPrefix?: string;
namePrefix?: string;
contents?: MultiMetaContent | null;
}) {
if (typeof contents === "undefined" || contents === null) {
return null;
}
const keyPrefix = propertyPrefix || namePrefix;
return (
<>
{contents.map((content, index) => {
if (
typeof content === "string" ||
typeof content === "number" ||
content instanceof URL
) {
return (
<Meta
key={keyPrefix + "_" + index}
{...(propertyPrefix
? { property: propertyPrefix }
: { name: namePrefix })}
content={content}
/>
);
} else {
return (
<ExtendMeta
key={keyPrefix + "_" + index}
namePrefix={namePrefix}
propertyPrefix={propertyPrefix}
content={content}
/>
);
}
})}
</>
);
}