This project aims at providing a set of hooks to populate <meta>
, ... for each page. With crawlers now supporting
client-side alterations it's important to support a fallback model for our <head>
tags. The dispatcher located in this
library will always make a queue of how we should fallback, ... This way we'll always have some information to give to a
visiting crawler.
npm i --save hoofd
## OR
yarn add hoofd
import { useMeta, useLink, useLang, useTitle, useTitleTemplate } from 'hoofd';
const App = () => {
// Will set <html lang="en">
useLang('en');
// Will set title to "Welcome to hoofd | 💭"
useTitleTemplate('%s | 💭');
useTitle('Welcome to hoofd');
useMeta({ name: 'author', content: 'Jovi De Croock' });
useLink({ rel: 'me', href: 'https://jovidecroock.com' });
return <p>hoofd</p>;
};
Or you can choose to
import { useHead, useLink } from 'hoofd';
const App = () => {
useHead({
title: 'Welcome to hoofd | 💭',
language: 'en',
metas: [{ name: 'author', content: 'Jovi De Croock' }],
});
useLink({ rel: 'me', href: 'https://jovidecroock.com' });
return <p>hoofd</p>;
};
If you need support for Preact you can import from hoofd/preact
instead.
There's a plugin that hooks in with Gatsby and that
will fill in the meta
, ... in your build process.
This package exports useTitle
, useTitleTemplate
, useMeta
, useLink
and useLang
. These hooks
are used to control information conveyed by the <head>
in an html document.
This hook accepts a string that will be used to set the document.title
, every time the
given string changes it will update the property.
This hook accepts a string, which will be used to format the result of useTitle
whenever
it updates. Similar to react-helmet, the placeholder %s
will be replaced with the title
.
This hook accepts the regular <meta>
properties, being name
, property
, httpEquiv
,
charset
and content
.
These have to be passed as an object and will update when content
changes.
This hook accepts the regular <link>
properties, being rel
, as
, media
,
href
, sizes
and crossorigin
.
This will update within the same useLink
but will never go outside
This hook accepts a string that will be used to set the lang
property on the
base <html>
tag. Every time this string gets updated this will be reflected in the dom.
We expose a method called toStatic
that will return the following properties:
- title, the current
title
dictated by the deepestuseTitleTemplate
anduseTitle
combination - lang, the current
lang
dictated by the deepestuseLang
- metas, an array of unique metas by
keyword
(property, ...) - links, the links aggregated from the render pass.
The reason we pass these as properties is to better support gatsby
, ...
If you need to stringify these you can use the following algo:
const stringify = (title, metas, links) => {
const visited = new Set();
return `
<title>${title}</title>
${metaQueue.reduce((acc, meta) => {
if (!visited.has(meta.charset ? meta.keyword : meta[meta.keyword])) {
visited.add(meta.charset ? meta.keyword : meta[meta.keyword]);
return `${acc}<meta ${meta.keyword}="${meta[meta.keyword]}"${
meta.charset ? '' : ` content="${meta.content}"`
}>`;
}
return acc;
}, '')}
${linkQueue.reduce((acc, link) => {
return `${acc}<link${Object.keys(link).reduce(
(properties, key) => `${properties} ${key}="${link[key]}"`,
''
)}>`;
}, '')}
`;
};
import { toStatic } from 'hoofd';
const reactStuff = renderToString();
const { metas, links, title, lang } = toStatic();
const stringified = stringify(title, metas, links);
const html = `
<!doctype html>
<html lang="${lang}">
<head>
${stringified}
</head>
<body>
<div id="content">
${reactStuff}
</div>
</body>
</html>
`;
- React support
- Add majority of types for meta and link.
- Concurrent friendly
- Preact support
- Support
<link>
- Stricter typings
- Document the hooks
- Document the dispatcher
- SSR support
- Consider moving from
doc.title = x
to inserting<title>x</title>
- Golf bytes
- improve typings, there are probably missing possibilities in
types.ts