Improved a11y and SEO

This commit is contained in:
Bad Manners 2024-11-05 19:42:21 -03:00
parent 74e6e66665
commit 815ca4d528
Signed by: badmanners
GPG key ID: 8C88292CCB075609
17 changed files with 80 additions and 112 deletions

View file

@ -1,42 +0,0 @@
User-agent: AI2Bot
User-agent: Ai2Bot-Dolma
User-agent: Amazonbot
User-agent: Applebot
User-agent: Applebot-Extended
User-agent: Bytespider
User-agent: CCBot
User-agent: ChatGPT-User
User-agent: Claude-Web
User-agent: ClaudeBot
User-agent: Diffbot
User-agent: FacebookBot
User-agent: FriendlyCrawler
User-agent: GPTBot
User-agent: Google-Extended
User-agent: GoogleOther
User-agent: GoogleOther-Image
User-agent: GoogleOther-Video
User-agent: ICC-Crawler
User-agent: ImagesiftBot
User-agent: Meta-ExternalAgent
User-agent: Meta-ExternalFetcher
User-agent: OAI-SearchBot
User-agent: PerplexityBot
User-agent: PetalBot
User-agent: Scrapy
User-agent: Timpibot
User-agent: VelenPublicWebCrawler
User-agent: Webzio-Extended
User-agent: YouBot
User-agent: anthropic-ai
User-agent: cohere-ai
User-agent: facebookexternalhit
User-agent: img2dataset
User-agent: omgili
User-agent: omgilibot
Disallow: /
User-agent: *
Disallow: .htaccess
Disallow: /stories/drafts/
Disallow: /games/drafts/

View file

@ -54,7 +54,10 @@ const relatedBlogPosts = (await getEntries(props.relatedBlogPosts)).filter((post
labelInformationSection={t(props.lang, "blog/information_aria_label")} labelInformationSection={t(props.lang, "blog/information_aria_label")}
labelArticleSection={t(props.lang, "blog/article_aria_label")} labelArticleSection={t(props.lang, "blog/article_aria_label")}
> >
<meta slot="head" property="og:description" content={props.description} /> <Fragment slot="head">
<meta property="og:description" content={props.description} />
<meta name="description" content={props.description} />
</Fragment>
<Fragment slot="section-information"> <Fragment slot="section-information">
<Authors lang={props.lang}> <Authors lang={props.lang}>
{authorsList.map((author) => <UserComponent rel="author" class="p-author" user={author} lang={props.lang} />)} {authorsList.map((author) => <UserComponent rel="author" class="p-author" user={author} lang={props.lang} />)}

View file

@ -53,7 +53,7 @@ const isCurrentRoute = (path: string) =>
<img <img
loading="eager" loading="eager"
src={logo.src} src={logo.src}
alt="A pixelated metal briefcase over a background with a green gradient." alt="A pixelated metal briefcase over a green gradient background."
class="u-logo my-4 w-full max-w-[192px] rounded-sm border-2 border-green-800 shadow-md dark:border-green-950" class="u-logo my-4 w-full max-w-[192px] rounded-sm border-2 border-green-800 shadow-md dark:border-green-950"
width={192} width={192}
/> />

View file

@ -16,6 +16,7 @@ const authorsList = await getEntries(props.authors);
const relatedStories = (await getEntries(props.relatedStories)).filter((story) => !story.data.isDraft); const relatedStories = (await getEntries(props.relatedStories)).filter((story) => !story.data.isDraft);
const relatedGames = (await getEntries(props.relatedGames)).filter((game) => !game.data.isDraft); const relatedGames = (await getEntries(props.relatedGames)).filter((game) => !game.data.isDraft);
const relatedBlogPosts = (await getEntries(props.relatedBlogPosts)).filter((post) => !post.data.isDraft); const relatedBlogPosts = (await getEntries(props.relatedBlogPosts)).filter((post) => !post.data.isDraft);
const metaDescription = t(props.lang, "game/warnings", props.platforms, props.contentWarning);
--- ---
<PublishedContentLayout <PublishedContentLayout
@ -50,11 +51,10 @@ const relatedBlogPosts = (await getEntries(props.relatedBlogPosts)).filter((post
labelInformationSection={t(props.lang, "game/information_aria_label")} labelInformationSection={t(props.lang, "game/information_aria_label")}
labelArticleSection={t(props.lang, "game/article_aria_label")} labelArticleSection={t(props.lang, "game/article_aria_label")}
> >
<meta <Fragment slot="head">
slot="head" <meta property="og:description" content={metaDescription} />
property="og:description" <meta name="description" content={metaDescription} />
content={t(props.lang, "game/warnings", props.platforms, props.contentWarning)} </Fragment>
/>
<Fragment slot="section-information"> <Fragment slot="section-information">
<Authors lang={props.lang}> <Authors lang={props.lang}>
{ {

View file

@ -435,7 +435,7 @@ const returnTo = series
{props.posts.mastodon ? <MastodonComments lang={props.lang} {...props.posts.mastodon} /> : null} {props.posts.mastodon ? <MastodonComments lang={props.lang} {...props.posts.mastodon} /> : null}
</main> </main>
<footer <footer
class="pt-14 text-center text-xs text-black dark:text-white" class="bg-bm-300/[0.01] pt-14 text-center text-xs text-black dark:bg-green-950/[0.01] dark:text-white"
aria-label={t(props.lang, "published_content/copyright_aria_label")} aria-label={t(props.lang, "published_content/copyright_aria_label")}
> >
<span <span

View file

@ -21,6 +21,7 @@ const relatedStories = (await getEntries(props.relatedStories)).filter((story) =
const relatedGames = (await getEntries(props.relatedGames)).filter((game) => !game.data.isDraft); const relatedGames = (await getEntries(props.relatedGames)).filter((game) => !game.data.isDraft);
const relatedBlogPosts = (await getEntries(props.relatedBlogPosts)).filter((post) => !post.data.isDraft); const relatedBlogPosts = (await getEntries(props.relatedBlogPosts)).filter((post) => !post.data.isDraft);
const wordCount = props.wordCount?.toString(); const wordCount = props.wordCount?.toString();
const metaDescription = t(props.lang, "story/warnings", wordCount, props.contentWarning);
--- ---
<PublishedContentLayout <PublishedContentLayout
@ -61,11 +62,10 @@ const wordCount = props.wordCount?.toString();
labelInformationSection={t(props.lang, "story/information_aria_label")} labelInformationSection={t(props.lang, "story/information_aria_label")}
labelArticleSection={t(props.lang, "story/article_aria_label")} labelArticleSection={t(props.lang, "story/article_aria_label")}
> >
<meta <Fragment slot="head">
slot="head" <meta property="og:description" content={metaDescription} />
property="og:description" <meta name="description" content={metaDescription} />
content={t(props.lang, "story/warnings", wordCount, props.contentWarning)} </Fragment>
/>
<Fragment slot="section-information"> <Fragment slot="section-information">
<Authors lang={props.lang}> <Authors lang={props.lang}>
{authorsList.map((author) => <UserComponent rel="author" class="p-author" user={author} lang={props.lang} />)} {authorsList.map((author) => <UserComponent rel="author" class="p-author" user={author} lang={props.lang} />)}

View file

@ -3,7 +3,10 @@ import GalleryLayout from "@layouts/GalleryLayout.astro";
--- ---
<GalleryLayout pageTitle="404"> <GalleryLayout pageTitle="404">
<meta slot="head" property="og:description" content="Not found" /> <Fragment slot="head">
<meta property="og:description" content="Not found" />
<meta name="description" content="The requested link could not be found." />
</Fragment>
<h1 class="m-2 text-3xl font-semibold text-stone-800 dark:text-stone-100">404 &ndash; Not Found</h1> <h1 class="m-2 text-3xl font-semibold text-stone-800 dark:text-stone-100">404 &ndash; Not Found</h1>
<hr class="mb-3 ml-[2px] mt-2 h-[4px] max-w-xs rounded-sm bg-stone-800 dark:bg-stone-100" aria-hidden /> <hr class="mb-3 ml-[2px] mt-2 h-[4px] max-w-xs rounded-sm bg-stone-800 dark:bg-stone-100" aria-hidden />
<p class="my-4">The requested link could not be found. Make sure that the URL is correct.</p> <p class="my-4">The requested link could not be found. Make sure that the URL is correct.</p>

View file

@ -19,7 +19,10 @@ const posts = await Promise.all(
--- ---
<GalleryLayout pageTitle="Blog" class="h-feed"> <GalleryLayout pageTitle="Blog" class="h-feed">
<meta slot="head" property="og:description" content="Bad Manners || A game that I've gone and done." /> <Fragment slot="head">
<meta property="og:description" content="Bad Manners || Blabbing about anything." />
<meta name="description" content="A collection of blog posts written by Bad Manners." />
</Fragment>
<h1 class="p-name m-2 text-3xl font-semibold text-stone-800 dark:text-stone-100">Blog</h1> <h1 class="p-name m-2 text-3xl font-semibold text-stone-800 dark:text-stone-100">Blog</h1>
<hr class="mb-3 ml-[2px] mt-2 h-[4px] max-w-xs rounded-sm bg-stone-800 dark:bg-stone-100" aria-hidden /> <hr class="mb-3 ml-[2px] mt-2 h-[4px] max-w-xs rounded-sm bg-stone-800 dark:bg-stone-100" aria-hidden />
<div class="my-4 flex w-full"> <div class="my-4 flex w-full">

View file

@ -19,7 +19,10 @@ const games = await Promise.all(
--- ---
<GalleryLayout pageTitle="Games" class="h-feed"> <GalleryLayout pageTitle="Games" class="h-feed">
<meta slot="head" property="og:description" content="Bad Manners || A game that I've gone and done." /> <Fragment slot="head">
<meta property="og:description" content="Bad Manners || A game that I've gone and done." />
<meta name="description" content="A safe vore videogame created by Bad Manners." />
</Fragment>
<h1 class="p-name m-2 text-3xl font-semibold text-stone-800 dark:text-stone-100">Games</h1> <h1 class="p-name m-2 text-3xl font-semibold text-stone-800 dark:text-stone-100">Games</h1>
<hr class="mb-3 ml-[2px] mt-2 h-[4px] max-w-xs rounded-sm bg-stone-800 dark:bg-stone-100" aria-hidden /> <hr class="mb-3 ml-[2px] mt-2 h-[4px] max-w-xs rounded-sm bg-stone-800 dark:bg-stone-100" aria-hidden />
<div class="my-4 flex w-full"> <div class="my-4 flex w-full">

View file

@ -152,19 +152,22 @@ if (featuredItems.length > MAX_FEATURED_ITEMS) {
--- ---
<GalleryLayout pageTitle="Gallery" class="h-feed"> <GalleryLayout pageTitle="Gallery" class="h-feed">
<meta slot="head" property="og:description" content="Bad Manners || Welcome to my gallery!" /> <Fragment slot="head">
<meta property="og:description" content="Bad Manners || Welcome to my gallery!" />
<meta name="description" content="Find stories, games, and blog posts made by Bad Manners." />
</Fragment>
<h1 class="p-name m-2 text-3xl font-semibold text-stone-800 dark:text-stone-100">Gallery</h1> <h1 class="p-name m-2 text-3xl font-semibold text-stone-800 dark:text-stone-100">Gallery</h1>
<hr class="mb-3 ml-[2px] mt-2 h-[4px] max-w-xs rounded-sm bg-stone-800 dark:bg-stone-100" aria-hidden /> <hr class="mb-3 ml-[2px] mt-2 h-[4px] max-w-xs rounded-sm bg-stone-800 dark:bg-stone-100" aria-hidden />
<div class="p-summary"> <div class="p-summary">
<div class="my-4 flex"> <div class="my-4 flex">
<p class="grow"> <p class="grow">
Welcome to my corner of the Internet! If you're looking for my main page, <a Welcome to my corner of the Internet! <a
class="u-url text-link underline" class="u-url text-link underline"
href="https://badmanners.xyz" href="https://badmanners.xyz"
x-data={JSON.stringify({ href: "https://badmanners.xyz", suffix: "?ageVerified=true" })} x-data={JSON.stringify({ href: "https://badmanners.xyz", suffix: "?ageVerified=true" })}
x-bind:href="ageVerified ? href + suffix : href" x-bind:href="ageVerified ? href + suffix : href"
rel="me">click here</a rel="me">Check out my main page</a
>. > for more info.
</p> </p>
<a class="u-url text-link ml-2 p-1 md:mr-5" href="/feed.xml" rel="alternate" title="RSS feed" data-tooltip> <a class="u-url text-link ml-2 p-1 md:mr-5" href="/feed.xml" rel="alternate" title="RSS feed" data-tooltip>
<IconSquareRSS width="2rem" height="2rem" /> <IconSquareRSS width="2rem" height="2rem" />

View file

@ -7,7 +7,7 @@ export const GET: APIRoute = async () => {
"Disallow: /", "Disallow: /",
"", "",
"User-agent: *", "User-agent: *",
"Disallow: .htaccess", "Disallow: /.htaccess",
"Disallow: /stories/drafts/", "Disallow: /stories/drafts/",
"Disallow: /games/drafts/", "Disallow: /games/drafts/",
] ]

View file

@ -9,7 +9,10 @@ import GalleryLayout from "@layouts/GalleryLayout.astro";
</script> </script>
<GalleryLayout pageTitle="Search"> <GalleryLayout pageTitle="Search">
<meta slot="head" property="og:description" content="Bad Manners || Search" /> <Fragment slot="head">
<meta property="og:description" content="Bad Manners || Search" />
<meta name="description" content="Search for stories, games, and blog posts made by Bad Manners." />
</Fragment>
<h1 class="m-2 text-3xl font-semibold text-stone-800 dark:text-stone-100">Search</h1> <h1 class="m-2 text-3xl font-semibold text-stone-800 dark:text-stone-100">Search</h1>
<hr class="mb-3 ml-[2px] mt-2 h-[4px] max-w-xs rounded-sm bg-stone-800 dark:bg-stone-100" aria-hidden /> <hr class="mb-3 ml-[2px] mt-2 h-[4px] max-w-xs rounded-sm bg-stone-800 dark:bg-stone-100" aria-hidden />
<SearchComponent id="search" className="pagefind-ui my-4" /> <SearchComponent id="search" className="pagefind-ui my-4" />

View file

@ -30,7 +30,10 @@ const totalPages = Math.ceil(page.total / page.size);
--- ---
<GalleryLayout pageTitle="Stories" class="h-feed"> <GalleryLayout pageTitle="Stories" class="h-feed">
<meta slot="head" property="og:description" content={`Bad Manners || ${page.total} stories.`} /> <Fragment slot="head">
<meta property="og:description" content="Bad Manners || Stories written by yours truly." />
<meta name="description" content="Safe vore stories written by Bad Manners." />
</Fragment>
<h1 class="p-name m-2 grow text-3xl font-semibold text-stone-800 dark:text-stone-100">Stories</h1> <h1 class="p-name m-2 grow text-3xl font-semibold text-stone-800 dark:text-stone-100">Stories</h1>
<hr class="mb-3 ml-[2px] mt-2 h-[4px] max-w-xs rounded-sm bg-stone-800 dark:bg-stone-100" aria-hidden /> <hr class="mb-3 ml-[2px] mt-2 h-[4px] max-w-xs rounded-sm bg-stone-800 dark:bg-stone-100" aria-hidden />
<div class="my-4 flex"> <div class="my-4 flex">
@ -48,28 +51,25 @@ const totalPages = Math.ceil(page.total / page.size);
} / {page.total} } / {page.total}
</p> </p>
<div class="mx-auto mb-6 mt-2 flex w-fit rounded-lg border border-stone-400 dark:border-stone-500"> <div class="mx-auto mb-6 mt-2 flex w-fit rounded-lg border border-stone-400 dark:border-stone-500">
{
page.url.prev && (
<a
class="text-link border-r border-stone-400 px-2 py-1 underline dark:border-stone-500"
rel="prev"
href={page.url.prev}
>
Previous page
</a>
)
}
{ {
[...Array(totalPages).keys()] [...Array(totalPages).keys()]
.map((p) => p + 1) .map((p) => p + 1)
.map((p) => .map((p) =>
p === page.currentPage ? ( p === page.currentPage ? (
<span class="border-r border-stone-400 px-4 py-1 font-semibold text-stone-900 dark:border-stone-500 dark:text-stone-50"> <span
class:list={[
p === 1 || "border-l",
"border-stone-400 px-4 py-1 font-semibold text-stone-900 dark:border-stone-500 dark:text-stone-50",
]}
>
{p} {p}
</span> </span>
) : ( ) : (
<a <a
class="text-link border-r border-stone-400 px-2 py-1 underline dark:border-stone-500" class:list={[
p === 1 || "border-l",
"text-link border-stone-400 px-2 py-1 underline dark:border-stone-500",
]}
href={p === 1 ? "/stories" : `/stories/${p}`} href={p === 1 ? "/stories" : `/stories/${p}`}
> >
{p} {p}
@ -77,13 +77,6 @@ const totalPages = Math.ceil(page.total / page.size);
), ),
) )
} }
{
page.url.next && (
<a class="text-link px-2 py-1 underline" rel="next" href={page.url.next}>
Next page
</a>
)
}
</div> </div>
<ul class="flex flex-wrap items-start justify-center gap-4 text-center md:justify-normal"> <ul class="flex flex-wrap items-start justify-center gap-4 text-center md:justify-normal">
{ {
@ -144,28 +137,25 @@ const totalPages = Math.ceil(page.total / page.size);
} }
</ul> </ul>
<div class="mx-auto my-6 flex w-fit rounded-lg border border-stone-400 dark:border-stone-500"> <div class="mx-auto my-6 flex w-fit rounded-lg border border-stone-400 dark:border-stone-500">
{
page.url.prev && (
<a
class="text-link border-r border-stone-400 px-2 py-1 underline dark:border-stone-500"
rel="prev"
href={page.url.prev}
>
Previous page
</a>
)
}
{ {
[...Array(totalPages).keys()] [...Array(totalPages).keys()]
.map((p) => p + 1) .map((p) => p + 1)
.map((p) => .map((p) =>
p === page.currentPage ? ( p === page.currentPage ? (
<span class="border-r border-stone-400 px-4 py-1 font-semibold text-stone-900 dark:border-stone-500 dark:text-stone-50"> <span
class:list={[
p === 1 || "border-l",
"border-stone-400 px-4 py-1 font-semibold text-stone-900 dark:border-stone-500 dark:text-stone-50",
]}
>
{p} {p}
</span> </span>
) : ( ) : (
<a <a
class="text-link border-r border-stone-400 px-2 py-1 underline dark:border-stone-500" class:list={[
p === 1 || "border-l",
"text-link border-stone-400 px-2 py-1 underline dark:border-stone-500",
]}
href={p === 1 ? "/stories" : `/stories/${p}`} href={p === 1 ? "/stories" : `/stories/${p}`}
> >
{p} {p}
@ -173,12 +163,5 @@ const totalPages = Math.ceil(page.total / page.size);
), ),
) )
} }
{
page.url.next && (
<a class="text-link px-2 py-1 underline" rel="next" href={page.url.next}>
Next page
</a>
)
}
</div> </div>
</GalleryLayout> </GalleryLayout>

View file

@ -22,11 +22,13 @@ const mainChaptersWithSummaries = mainChapters.filter((story) => story.data.summ
--- ---
<GalleryLayout pageTitle={series.data.name} enablePagefind={true} class="h-feed"> <GalleryLayout pageTitle={series.data.name} enablePagefind={true} class="h-feed">
<meta <Fragment slot="head">
slot="head" <meta property="og:description" content="The Lost of the Marshes || The story of Quince, Nikili, and Suu." />
property="og:description" <meta
content="The Lost of the Marshes || The story of Quince, Nikili, and Suu." name="description"
/> content="An unfinished vore-centric series centered around a dragon and his newfound friends."
/>
</Fragment>
<h1 class="p-name m-2 text-3xl font-semibold text-stone-800 dark:text-stone-100">{series.data.name}</h1> <h1 class="p-name m-2 text-3xl font-semibold text-stone-800 dark:text-stone-100">{series.data.name}</h1>
<hr class="mb-3 ml-[2px] mt-2 h-[4px] max-w-xs rounded-sm bg-stone-800 dark:bg-stone-100" aria-hidden /> <hr class="mb-3 ml-[2px] mt-2 h-[4px] max-w-xs rounded-sm bg-stone-800 dark:bg-stone-100" aria-hidden />
<p class="p-summary my-4"> <p class="p-summary my-4">

View file

@ -76,7 +76,10 @@ if (uncategorizedTagsSet.size > 0) {
--- ---
<GalleryLayout pageTitle="Tags"> <GalleryLayout pageTitle="Tags">
<meta property="og:description" slot="head" content="Bad Manners || Find all content with a specific tag." /> <Fragment slot="head">
<meta property="og:description" content="Bad Manners || Find all content with a specific tag." />
<meta name="description" content="Find all content by Bad Manners with a specific tag." />
</Fragment>
<h1 class="m-2 text-3xl font-semibold text-stone-800 dark:text-stone-100">All available tags</h1> <h1 class="m-2 text-3xl font-semibold text-stone-800 dark:text-stone-100">All available tags</h1>
<hr class="mb-3 ml-[2px] mt-2 h-[4px] max-w-xs rounded-sm bg-stone-800 dark:bg-stone-100" aria-hidden /> <hr class="mb-3 ml-[2px] mt-2 h-[4px] max-w-xs rounded-sm bg-stone-800 dark:bg-stone-100" aria-hidden />
<section class="my-2" aria-labelledby="category-series"> <section class="my-2" aria-labelledby="category-series">

View file

@ -24,6 +24,7 @@ const { badTag } = Astro.props;
<GalleryLayout pageTitle={`Works tagged "${badTag}"`}> <GalleryLayout pageTitle={`Works tagged "${badTag}"`}>
<Fragment slot="head"> <Fragment slot="head">
<meta content="No." property="og:description" /> <meta content="No." property="og:description" />
<meta name="description" content={`There won't ever be works tagged "${badTag}" in this place.`} />
<meta name="robots" content="noindex" /> <meta name="robots" content="noindex" />
</Fragment> </Fragment>
<h1 class="p-name m-2 text-3xl font-semibold text-stone-800 dark:text-stone-100">Works tagged "{badTag}"</h1> <h1 class="p-name m-2 text-3xl font-semibold text-stone-800 dark:text-stone-100">Works tagged "{badTag}"</h1>

View file

@ -137,7 +137,10 @@ const totalWorksWithTag = t(
--- ---
<GalleryLayout pageTitle={`Works tagged "${props.tag}"`}> <GalleryLayout pageTitle={`Works tagged "${props.tag}"`}>
<meta slot="head" content={`Bad Manners || ${totalWorksWithTag || props.tag}`} property="og:description" /> <Fragment slot="head">
<meta content={`Bad Manners || ${totalWorksWithTag}`} property="og:description" />
<meta name="description" content={`Works by Bad Manners tagged with "${props.tag}".`} />
</Fragment>
<h1 class="p-name m-2 text-3xl font-semibold text-stone-800 dark:text-stone-100">Works tagged "{props.tag}"</h1> <h1 class="p-name m-2 text-3xl font-semibold text-stone-800 dark:text-stone-100">Works tagged "{props.tag}"</h1>
<hr class="mb-3 ml-[2px] mt-2 h-[4px] max-w-xs rounded-sm bg-stone-800 dark:bg-stone-100" aria-hidden /> <hr class="mb-3 ml-[2px] mt-2 h-[4px] max-w-xs rounded-sm bg-stone-800 dark:bg-stone-100" aria-hidden />
<div class="my-4"> <div class="my-4">