aboutsummaryrefslogtreecommitdiffstats
path: root/src/components/templates/layout
diff options
context:
space:
mode:
authorArmand Philippot <git@armandphilippot.com>2023-12-14 15:30:34 +0100
committerArmand Philippot <git@armandphilippot.com>2023-12-14 16:30:04 +0100
commit7063b199b4748a9c354ed37e64cdc84c512f2c0c (patch)
tree7506c3003c56b49a248e9adb40be610780bb540e /src/components/templates/layout
parent85c4c42bd601270d7be0f34a0767a34bb85e29bb (diff)
refactor(pages): rewrite helpers to output schema in json-ld format
* make sure url are absolutes * nest breadcrumb schema in webpage schema * trim HTML tags from content/description * use a regular script instead of next/script (with the latter the schema is not updated on route change) * place the script in document head * add keywords, wordCount and readingTime keys in BlogPosting schema * fix breadcrumbs in search page (without query) * add tests (a `MatchInlineSnapshot` will be better but Prettier 3 is not supported yet)
Diffstat (limited to 'src/components/templates/layout')
-rw-r--r--src/components/templates/layout/layout.tsx47
-rw-r--r--src/components/templates/layout/site-header/site-header.tsx7
2 files changed, 6 insertions, 48 deletions
diff --git a/src/components/templates/layout/layout.tsx b/src/components/templates/layout/layout.tsx
index 4dfe5f3..2a6ac2e 100644
--- a/src/components/templates/layout/layout.tsx
+++ b/src/components/templates/layout/layout.tsx
@@ -1,19 +1,11 @@
-import Script from 'next/script';
import type { FC, ReactElement, ReactNode } from 'react';
import { useIntl } from 'react-intl';
-import type { Person, SearchAction, WebSite, WithContext } from 'schema-dts';
import type { NextPageWithLayoutOptions } from '../../../types';
-import { CONFIG } from '../../../utils/config';
-import { ROUTES } from '../../../utils/constants';
import { ButtonLink, Main } from '../../atoms';
import styles from './layout.module.scss';
import { SiteFooter } from './site-footer';
import { SiteHeader, type SiteHeaderProps } from './site-header';
-export type QueryAction = SearchAction & {
- 'query-input': string;
-};
-
export type LayoutProps = Pick<SiteHeaderProps, 'isHome'> & {
/**
* The layout main content.
@@ -27,7 +19,6 @@ export type LayoutProps = Pick<SiteHeaderProps, 'isHome'> & {
* Render the base layout used by all pages.
*/
export const Layout: FC<LayoutProps> = ({ children, isHome }) => {
- const { baseline, copyright, locales, name, url } = CONFIG;
const intl = useIntl();
const messages = {
noScript: intl.formatMessage({
@@ -43,49 +34,11 @@ export const Layout: FC<LayoutProps> = ({ children, isHome }) => {
}),
};
- const searchActionSchema: QueryAction = {
- '@type': 'SearchAction',
- target: {
- '@type': 'EntryPoint',
- urlTemplate: `${url}${ROUTES.SEARCH}?s={search_term_string}`,
- },
- query: 'required',
- 'query-input': 'required name=search_term_string',
- };
- const brandingSchema: Person = {
- '@type': 'Person',
- name,
- url,
- jobTitle: baseline,
- image: '/armand-philippot.jpg',
- subjectOf: { '@id': `${url}` },
- };
- const schemaJsonLd: WithContext<WebSite> = {
- '@context': 'https://schema.org',
- '@id': `${url}`,
- '@type': 'WebSite',
- name,
- description: baseline,
- url,
- author: brandingSchema,
- copyrightYear: Number(copyright.startYear),
- creator: brandingSchema,
- editor: brandingSchema,
- inLanguage: locales.defaultLocale,
- potentialAction: searchActionSchema,
- };
-
const topId = 'top';
const mainId = 'main';
return (
<>
- <Script
- dangerouslySetInnerHTML={{ __html: JSON.stringify(schemaJsonLd) }}
- // eslint-disable-next-line react/jsx-no-literals -- Id allowed
- id="schema-layout"
- type="application/ld+json"
- />
<span id={topId} />
<noscript>
<div className={styles['noscript-spacing']} />
diff --git a/src/components/templates/layout/site-header/site-header.tsx b/src/components/templates/layout/site-header/site-header.tsx
index 3e06350..91add77 100644
--- a/src/components/templates/layout/site-header/site-header.tsx
+++ b/src/components/templates/layout/site-header/site-header.tsx
@@ -1,4 +1,5 @@
import { type ForwardRefRenderFunction, forwardRef } from 'react';
+import { AUTHOR_ID } from '../../../../utils/constants';
import { Header, type HeaderProps } from '../../../atoms';
import { SiteBranding } from './site-branding';
import styles from './site-header.module.scss';
@@ -16,7 +17,11 @@ const SiteHeaderWithRef: ForwardRefRenderFunction<
return (
<Header {...props} className={headerClass} ref={ref}>
- <SiteBranding className={styles.branding} isHome={isHome} />
+ <SiteBranding
+ className={styles.branding}
+ id={AUTHOR_ID}
+ isHome={isHome}
+ />
<SiteNavbar className={styles.navbar} />
</Header>
);