Open KemaneWright opened 1 year ago
Just dumping what we have been doing in a current project. Unsure if this is documentation worthy but perhaps it helps someone:
Metatag
We're basically just exposing what metatag is doing using the patch from this issue https://drupal.org/node/2945817.
Inside the next.js client we're including the computed metatag field in the fields list
Then we have a meta tags component which rebuilds the exposed metatag json in a format we want can use in the client.
Here a dump of the component (Favicons generated using https://realfavicongenerator.net/):
import Head from 'next/head'
interface MetaTagAttributes {
rel?: string
name?: string
href?: string
content?: string
property?: string
}
interface MetaTag {
tag: 'link' | 'meta' | 'title'
key?: string
attributes: MetaTagAttributes
}
interface MetaProps {
MetaTags: MetaTag[]
title: string
}
export function Meta({ MetaTags, title }: MetaProps) {
return (
<Head>
<title>{title}</title>
<link
rel="apple-touch-icon"
sizes="180x180"
href="/favicons/apple-touch-icon.png"
/>
<link
rel="icon"
type="image/png"
sizes="32x32"
href="/favicons/favicon-32x32.png"
/>
<link
rel="icon"
type="image/png"
sizes="16x16"
href="/favicons/favicon-16x16.png"
/>
<link rel="manifest" href="/favicons/site.webmanifest" />
<link
rel="mask-icon"
href="/favicons/safari-pinned-tab.svg"
color="#000066"
/>
<meta name="msapplication-TileColor" content="#010D7F" />
<meta name="theme-color" content="#010D7F" />
{MetaTags.map((metaTag) => {
metaTag.attributes = absoluteClientPaths(metaTag.attributes)
metaTag.key = getMetaTagKey(metaTag.attributes)
return <metaTag.tag {...metaTag.attributes} key={metaTag.key} />
})}
</Head>
)
}
function absoluteClientPaths(attributes: MetaTagAttributes): MetaTagAttributes {
// Handle images with next image
if (
attributes.rel === 'image_src' &&
attributes.href.startsWith(process.env.NEXT_PUBLIC_DRUPAL_BASE_URL)
) {
attributes.href = `${process.env.NEXT_PUBLIC_BASE_URL}/_next/image?url=${attributes.href}&w=1920&q=75`
}
if (
attributes.property === 'og:image' &&
attributes.content.startsWith(process.env.NEXT_PUBLIC_DRUPAL_BASE_URL)
) {
attributes.href = `${process.env.NEXT_PUBLIC_BASE_URL}/_next/image?url=${attributes.content}&w=1920&q=75`
}
// Handle absolute urls to the cms
if (attributes.href?.startsWith(process.env.NEXT_PUBLIC_DRUPAL_BASE_URL)) {
attributes.href = attributes.href?.replace(
process.env.NEXT_PUBLIC_DRUPAL_BASE_URL,
process.env.NEXT_PUBLIC_BASE_URL,
)
}
if (attributes.content?.startsWith(process.env.NEXT_PUBLIC_DRUPAL_BASE_URL)) {
attributes.content = attributes.content?.replace(
process.env.NEXT_PUBLIC_DRUPAL_BASE_URL,
process.env.NEXT_PUBLIC_BASE_URL,
)
}
return attributes
}
function getMetaTagKey(attributes: MetaTagAttributes): string {
return attributes.rel ?? attributes.name ?? attributes.property
}
Sitemap
We investigated options for achieving quite the same like Drupal is doing but failed. So we just use the Drupal sitemap.
For that we override the URL from the simple_sitemap module $config['simple_sitemap.settings']['base_url'] = $clientUrl;
and then add a rewrite to the client nextjs config:
...
async rewrites() {
return [
...
{
source: '/sitemap.xml',
destination: process.env.NEXT_PUBLIC_DRUPAL_BASE_URL + '/sitemap.xml',
},
]
},
...
GA and GTM are just injected into the client, without any connection to Drupal.
Would be awesome if there was some documentation on best practices and methods for implementing SEO features from Drupal into the Next.js site. Like Metatag & XML Sitemap, GA, GTM, etc.