Ecosyste.ms: Awesome
An open API service indexing awesome lists of open source software.
https://github.com/JoviDeCroock/hoofd
Hooks to populate the html head.
https://github.com/JoviDeCroock/hoofd
head html react react-hooks seo
Last synced: about 16 hours ago
JSON representation
Hooks to populate the html head.
- Host: GitHub
- URL: https://github.com/JoviDeCroock/hoofd
- Owner: 0no-co
- License: mit
- Created: 2020-04-02T14:52:25.000Z (almost 5 years ago)
- Default Branch: main
- Last Pushed: 2024-04-04T01:15:07.000Z (10 months ago)
- Last Synced: 2024-05-23T07:06:44.778Z (8 months ago)
- Topics: head, html, react, react-hooks, seo
- Language: TypeScript
- Homepage:
- Size: 925 KB
- Stars: 335
- Watchers: 4
- Forks: 15
- Open Issues: 2
-
Metadata Files:
- Readme: README.md
- Changelog: CHANGELOG.md
- Funding: .github/FUNDING.yml
- License: LICENSE
- Code of conduct: CODE_OF_CONDUCT.md
Awesome Lists containing this project
- awesome-list - hoofd
README
# Hoofd
[![npm version](https://badgen.net/npm/v/hoofd)](https://www.npmjs.com/package/hoofd)
[![Bundle size](https://badgen.net/bundlephobia/minzip/hoofd)](https://badgen.net/bundlephobia/minzip/hoofd)This project aims at providing a set of hooks to populate ``, ... for each page. With crawlers now supporting
client-side alterations it's important to support a fallback model for our `` 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.```sh
npm i --save hoofd
## OR
yarn add hoofd
``````jsx
import { useMeta, useLink, useLang, useTitle, useTitleTemplate } from 'hoofd';const App = () => {
// Will set
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
hoofd
;
};
```Or you can choose to
```jsx
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
hoofd
;
};
```## Preact
If you need support for [Preact](https://preactjs.com/) you can import from `hoofd/preact` instead.
## Gatsby
There's a plugin that hooks in with [Gatsby](https://www.npmjs.com/package/gatsby-plugin-hoofd) and that
will fill in the `meta`, ... in your build process.## Hooks
This package exports `useTitle`, `useTitleTemplate`, `useMeta`, `useLink` and `useLang`. These hooks
are used to control information conveyed by the `` in an html document.### useTitle
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.### useTitleTemplate
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`.### useMeta
This hook accepts the regular `` properties, being `name`, `property`, `httpEquiv`,
`charset` and `content`.These have to be passed as an object and will update when `content` changes.
### useLink
This hook accepts the regular `` properties, being `rel`, `as`, `media`,
`href`, `sizes` and `crossorigin`.This will update within the same `useLink` but will never go outside
### useLang
This hook accepts a string that will be used to set the `lang` property on the
base `` tag. Every time this string gets updated this will be reflected in the dom.### useScript
This hook accepts a few arguments and will lead to an injection of a script tag into the dispatcher (during ssr)
or the DOM (during csr).- src?: this can be a location where the script lives, for example `public/x.js` or an inline script for example `data:application/javascript,alert("yolo")`.
- id?: a unique identifier used for querying the script tag. Atleast one among `src` and `id` prop is mandatory.
- text?: this sets the inner `text` on the script tag. Can be used for adding [embedded data](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/script#embedding_data_in_html), [rich text data](https://developers.google.com/search/docs/guides/intro-structured-data).
- type?: this sets the `type` attribute on the script tag.
- async?: this sets the `async` attribute on the script tag.
- defer?: this sets the `defer` attribute on the script tag.
- module?: this property will override the `type` atrribute on the script tag with a value of `module`.
- crossorigin?: 'anonymous' | 'use-credentials';
- integrity?: string;## SSR
We expose a method called `toStatic` that will return the following properties:
- title, the current `title` dictated by the deepest `useTitleTemplate` and `useTitle` combination
- lang, the current `lang` dictated by the deepest `useLang`
- 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:
```js
const stringify = (title, metas, links) => {
const stringifyTag = (tagName, tags) =>
tags.reduce((acc, tag) =>
`${acc}<${tagName}${Object.keys(tag).reduce(
(properties, key) => `${properties} ${key}="${tag[key]}"`,
''
)}>`
, '');return `
${title}${stringifyTag('meta', metas)}
${stringifyTag('link', links)}
`;
};
``````js
import { toStatic } from 'hoofd';const reactStuff = renderToString();
const { metas, links, title, lang } = toStatic();
const stringified = stringify(title, metas, links);const html = `
${stringified}
${reactStuff}
`;
```### Context API
By default this package relies on a statically-initialized context provider to accumulate and
dispatch `` and `` changes. In cases where you may want to control the Dispatcher
instance used, this module exports a `HoofdProvider` context provider and `createDispatcher`
function for creating valid context instances.```jsx
import { createDispatcher, HoofdProvider } from 'hoofd';function ssr(App) {
const dispatcher = createDispatcher();
const wrappedApp = (
);
const markup = renderToString(wrappedApp);
const { metas, links, title, lang } = dispatcher.toStatic();// See example above for potential method to consume these static results.
}
```