diff --git a/src/components/AppLayout.tsx b/src/components/AppLayout.tsx index aff196b..8bf009a 100644 --- a/src/components/AppLayout.tsx +++ b/src/components/AppLayout.tsx @@ -117,6 +117,8 @@ export function AppLayout(props: Immutable): JSX.Element { const ogTitle = title ?? navTitle ?? prettySlug(router.asPath.split("/").pop()); + const metaTitle = `${titlePrefix} - ${ogTitle}`; + const metaDescription = description ?? langui.default_description ?? ""; useEffect(() => { @@ -191,16 +193,16 @@ export function AppLayout(props: Immutable): JSX.Element { mobile:grid-rows-[1fr_5rem] mobile:[grid-template-areas:'content''navbar']`} > - {`${titlePrefix} - ${ogTitle}`} - - - + {metaTitle} - + + + + + + + ): JSX.Element { > - - - {/* Background when navbar is opened */} diff --git a/src/components/PostPage.tsx b/src/components/PostPage.tsx index b51d0ac..25fcce1 100644 --- a/src/components/PostPage.tsx +++ b/src/components/PostPage.tsx @@ -1,4 +1,5 @@ import { AppStaticProps } from "graphql/getAppStaticProps"; +import { getDescription } from "helpers/description"; import { prettySlug } from "helpers/formatters"; import { getStatusDescription } from "helpers/others"; import { Immutable, PostWithTranslations } from "helpers/types"; @@ -168,6 +169,11 @@ export function PostPage(props: Immutable): JSX.Element { return ( ; + categories?: Immutable; +} + +export function getDescription(props: Description): string { + const { langui, description: text, type, categories } = props; + + let description = ""; + + // TEXT + if (text) { + description += prettyMarkdown(text); + description += "\n\n"; + } + + // TYPE + if (type?.data) { + description += `${langui.type}: `; + + description += `(${ + type.data.attributes?.titles?.[0]?.title ?? + prettySlug(type.data.attributes?.slug) + })`; + + description += "\n"; + } + + // CATEGORIES + if (categories?.data && categories.data.length > 0) { + description += `${langui.categories}: `; + description += prettyChip( + categories.data.map((category) => category.attributes?.short) + ); + + description += "\n"; + } + + return description; +} + +function prettyMarkdown(markdown: string): string { + return markdown.replace(/[*]/gu, "").replace(/[_]/gu, ""); +} + +function prettyChip(items: (string | undefined)[]): string { + return items + .filter((item) => item !== undefined) + .map((item) => `(${item})`) + .join(" "); +} diff --git a/src/helpers/types.ts b/src/helpers/types.ts index 3646a52..67eb1c7 100644 --- a/src/helpers/types.ts +++ b/src/helpers/types.ts @@ -9,7 +9,7 @@ export interface PostWithTranslations extends Omit { translations: NonNullable; } -type Content = NonNullable< +export type Content = NonNullable< NonNullable["data"][number]["attributes"] >; diff --git a/src/pages/contents/[slug]/index.tsx b/src/pages/contents/[slug]/index.tsx index 90dd3cb..0d3fc40 100644 --- a/src/pages/contents/[slug]/index.tsx +++ b/src/pages/contents/[slug]/index.tsx @@ -18,6 +18,7 @@ import { ToolTip } from "components/ToolTip"; import { AppStaticProps, getAppStaticProps } from "graphql/getAppStaticProps"; import { getReadySdk } from "graphql/sdk"; import { getNextContent, getPreviousContent } from "helpers/contents"; +import { getDescription } from "helpers/description"; import { prettyinlineTitle, prettyLanguage, @@ -389,24 +390,6 @@ export default function Content(props: Immutable): JSX.Element { ); - let description = ""; - if (content.type?.data) { - description += `${langui.type}: `; - - description += - content.type.data.attributes?.titles?.[0]?.title ?? - prettySlug(content.type.data.attributes?.slug); - - description += "\n"; - } - if (content.categories?.data && content.categories.data.length > 0) { - description += `${langui.categories}: `; - description += content.categories.data - .map((category) => category.attributes?.short) - .join(" | "); - description += "\n"; - } - return ( ): JSX.Element { ) : prettySlug(content.slug) } + description={getDescription({ + langui: langui, + description: selectedTranslation?.description, + type: content.type, + categories: content.categories, + })} thumbnail={content.thumbnail?.data?.attributes ?? undefined} contentPanel={contentPanel} subPanel={subPanel} - description={description} {...props} /> ); diff --git a/src/pages/contents/index.tsx b/src/pages/contents/index.tsx index 36aaeb9..da4b1bd 100644 --- a/src/pages/contents/index.tsx +++ b/src/pages/contents/index.tsx @@ -244,20 +244,8 @@ export async function getStaticProps( }); if (!contents.contents) return { notFound: true }; contents.contents.data.sort((a, b) => { - const titleA = a.attributes?.translations?.[0] - ? prettyinlineTitle( - a.attributes.translations[0].pre_title, - a.attributes.translations[0].title, - a.attributes.translations[0].subtitle - ) - : a.attributes?.slug ?? ""; - const titleB = b.attributes?.translations?.[0] - ? prettyinlineTitle( - b.attributes.translations[0].pre_title, - b.attributes.translations[0].title, - b.attributes.translations[0].subtitle - ) - : b.attributes?.slug ?? ""; + const titleA = a.attributes?.slug ?? ""; + const titleB = b.attributes?.slug ?? ""; return titleA.localeCompare(titleB); });