feat: structured data markup

This commit is contained in:
DIYgod 2022-11-24 16:40:08 +00:00
parent 214ffc7a22
commit 89fb6269e9
No known key found for this signature in database
GPG Key ID: D159328F47A80DCA
4 changed files with 92 additions and 42 deletions

View File

@ -4,7 +4,6 @@ import { UniLink } from "~/components/ui/UniLink"
import { Note, Profile } from "~/lib/types"
import { CSB_SCAN } from "~/lib/env"
import { useEffect, useState } from "react"
import { useGetUserSites } from "~/queries/site"
import { CharacterFloatCard } from "~/components/common/CharacterFloatCard"
import { getSiteLink } from "~/lib/helpers"
import { Avatar } from "~/components/ui/Avatar"
@ -12,9 +11,9 @@ import { Avatar } from "~/components/ui/Avatar"
export const PostMeta: React.FC<{
page: Note
site?: Profile | null
}> = ({ page, site }) => {
author?: Profile | null
}> = ({ page, site, author }) => {
const [isMounted, setIsMounted] = useState(false)
const author = useGetUserSites(page.authors[0])
useEffect(() => {
setIsMounted(true)
@ -49,29 +48,28 @@ export const PostMeta: React.FC<{
</span>
</>
) : null}
{author.data?.[0].username &&
site?.username !== author.data?.[0].username && (
<>
<span className="inline-flex items-center">
<CharacterFloatCard siteId={author.data[0].username}>
<UniLink
href={getSiteLink({
subdomain: author.data?.[0].username,
})}
className="cursor-pointer hover:text-zinc-600 inline-flex items-center"
>
<Avatar
className="mr-1"
images={author.data[0].avatars || []}
size={19}
name={author.data[0].name}
/>
<span>{author.data[0].name}</span>
</UniLink>
</CharacterFloatCard>
</span>
</>
)}
{author?.username && site?.username !== author?.username && (
<>
<span className="inline-flex items-center">
<CharacterFloatCard siteId={author?.username}>
<UniLink
href={getSiteLink({
subdomain: author?.username,
})}
className="cursor-pointer hover:text-zinc-600 inline-flex items-center"
>
<Avatar
className="mr-1"
images={author?.avatars || []}
size={19}
name={author?.name}
/>
<span>{author?.name}</span>
</UniLink>
</CharacterFloatCard>
</span>
</>
)}
<UniLink
className="xlog-post-blockchain inline-block"
href={

View File

@ -2,6 +2,7 @@ import {
prefetchGetSite,
prefetchGetSiteSubscriptions,
prefetchGetSiteToSubscriptions,
prefetchGetUserSites,
} from "~/queries/site.server"
import { prefetchGetPagesBySite } from "~/queries/page.server"
import { PageVisibilityEnum } from "~/lib/types"
@ -48,6 +49,10 @@ export const getServerSideProps = async (
if (!page || new Date(page!.date_published) > new Date()) {
reject(notFound())
}
if (page?.authors[0]) {
await prefetchGetUserSites(page?.authors[0], queryClient)
}
} catch (error) {
reject(error)
}

View File

@ -2,34 +2,71 @@ import { PageContent } from "../common/PageContent"
import { PostMeta } from "./PostMeta"
import { PostFooter } from "./PostFooter"
import { Note, Profile } from "~/lib/types"
import Head from "next/head"
import { useGetUserSites } from "~/queries/site"
import { getSiteLink } from "~/lib/helpers"
export const SitePage: React.FC<{
page?: Note | null
site?: Profile | null
}> = ({ page, site }) => {
const author = useGetUserSites(page?.authors[0])
function addPageJsonLd() {
return {
__html: `{
"@context": "https://schema.org",
"@type": "BlogPosting",
"headline": "${page?.title}",
"image": [
"${page?.cover}"
],
"datePublished": "${page?.date_published}",
"dateModified": "${page?.date_updated}",
"author": [{
"@type": "Person",
"name": "${author?.data?.[0]?.name}",
"url": "${getSiteLink({
subdomain: author?.data?.[0].username || "",
})}"
}]
}`,
}
}
return (
<>
<Head>
<script
type="application/ld+json"
dangerouslySetInnerHTML={addPageJsonLd()}
/>
</Head>
{page?.preview && (
<div className="fixed top-0 left-0 w-full text-center text-orange-500 bg-gray-100 py-2 opacity-80 text-sm">
Currently in private preview mode, the content is different from the
public
</div>
)}
<div>
{page?.tags?.includes("post") ? (
<h2 className="xlog-post-title text-4xl font-bold">{page.title}</h2>
) : (
<h2 className="xlog-post-title text-xl font-bold page-title">
{page?.title}
</h2>
)}
{page?.tags?.includes("post") && <PostMeta page={page} site={site} />}
</div>
<PageContent
className="mt-10"
content={page?.body?.content}
toc={true}
></PageContent>
<article>
<div>
{page?.tags?.includes("post") ? (
<h2 className="xlog-post-title text-4xl font-bold">{page.title}</h2>
) : (
<h2 className="xlog-post-title text-xl font-bold page-title">
{page?.title}
</h2>
)}
{page?.tags?.includes("post") && (
<PostMeta page={page} site={site} author={author.data?.[0]} />
)}
</div>
<PageContent
className="mt-10"
content={page?.body?.content}
toc={true}
></PageContent>
</article>
{page?.metadata && <PostFooter page={page} />}
</>
)

View File

@ -44,7 +44,7 @@ export const prefetchGetSites = async (
queryClient: QueryClient,
) => {
const key = ["getSites", input]
return await queryClient.fetchQuery(key, async () => {
await queryClient.fetchQuery(key, async () => {
return cacheGet(key, () => siteModel.getSites(input))
})
}
@ -65,3 +65,13 @@ export const fetchGetNotifications = async (
)
})
}
export const prefetchGetUserSites = async (
address: string,
queryClient: QueryClient,
) => {
const key = ["getUserSites", address]
await queryClient.prefetchQuery(key, async () => {
return cacheGet(key, () => siteModel.getUserSites(address))
})
}