Browsers and search engines expose many powerful capabilities to websites through special HTML elements and attributes:
- You can update the contents of the browser’s tab for your page using the
<title>
and<link rel="icon">
elements - You can control the way search engines index your pages using the
robots
<meta>
tag - You can serialize non-HTML content into the HTML document for use on the client (this is often used to send data to the client that is used to start the application on the client)
Quilt provides a collection of component-friendly APIs for manipulating these special parts of the HTML document, both during client- and server-side rendering.
This guide assumes you are using the automatic server-side rendering provided by Quilt. This powerful feature creates a server runtime that will render your application and collect the “server side effects”, including using the HTML utilities documented in this guide. If you are writing your own custom server-side rendering setup, or are using Quilt in a non-standard way, make sure you follow the guide on @quilted/react-html
, which covers how the server-side rendering of the HTML document works under the hood.
This guide also assumes that your application renders the <AppContext>
component provided by @quilted/quilt
, which takes care of updating HTML details on the client.
You often need to add elements to the <head>
of your page. Many aspects of the browser’s behavior can be influenced through <meta>
tags, and metadata for search engine optimization (SEO) are commonly placed in this part of the document. Quilt provides a collection of hooks and components that you can use in any component of your app to add these special tags.
To add a custom document title, you can use the useTitle
hook, or the Title
component:
import {useTitle, Title} from '@quilted/react-html';
// also available from '@quilted/quilt/html'
export function App({user}: {user: string}) {
useTitle(`Welcome, ${user}!`);
// or...
return <Title>Welcome, {user}!</Title>;
}
To add additional <meta>
tags to the <head>
, you can use the useMeta
hook, or the Meta
component:
import {useMeta, Meta} from '@quilted/react-html';
// also available from '@quilted/quilt/html'
export function App() {
useMeta({name: 'description', content: 'An app for doing fun stuff!'});
// or...
return <Meta name="description" content="An app for doing fun stuff!" />;
}
Quilt also comes with a few components that provide more tailored APIs for common <meta>
tags. The useViewport
hook (or the Viewport
component) can be used to set the viewport <meta>
tag, and the useThemeColor
hook (or the ThemeColor
component) can be used to set the theme-color
<meta>
tag:
import {
useViewport,
useThemeColor,
Viewport,
ThemeColor,
} from '@quilted/react-html';
// also available from '@quilted/quilt/html'
export function App() {
useViewport({cover: true});
useThemeColor('#BADA55');
// or...
return (
<>
<Viewport cover />
<ThemeColor value="#BADA55" />
</>
);
}
The useSearchRobots
hook and SearchRobots
component can be used to set the robots
<meta>
tag
import {useSearchRobots, SearchRobots} from '@quilted/react-html';
// also available from '@quilted/quilt/html'
export function App() {
useSearchRobots({
translate: false,
snippet: {maxLength: 20},
imagePreviews: {maxSize: 'large'},
});
// or...
return (
<SearchRobots
translate={false}
snippet={{maxLength: 20}}
imagePreviews={{maxSize: 'large'}}
/>
);
}
To add additional <link>
tags to the <head>
, you can use the useLink
hook, or the Link
component:
import {useLink, Link} from '@quilted/react-html';
// also available from '@quilted/quilt/html'
export function App() {
useLink({
rel: 'apple-touch-icon-precomposed',
href: 'apple-icon-114.png',
sizes: '114x114',
type: 'image/png',
});
// or...
return (
<Link
rel="apple-touch-icon-precomposed"
href="apple-icon-114.png"
sizes="114x114"
type="image/png"
/>
);
}
Like with <meta>
tags, Quilt provides a convenience components for interacting with common uses of <link>
tags. You can use the useFavicon
hook (or Favicon
component) to set the favicon:
import {useFavicon, Favicon} from '@quilted/react-html';
// also available from '@quilted/quilt/html'
export function App() {
useFavicon('https://fav.farm/💩');
// or...
return <Favicon source="https://fav.farm/💩" />;
}
The Favicon
component comes with a few useful shortcuts for special options:
import {Favicon} from '@quilted/react-html';
export function BlankFavicon() {
// Provides a completely empty image, which prevents browsers from trying
// to make a request to your backend for a favicon.
return <Favicon blank />;
}
export function EmojiFavicon() {
// Uses the emoji as a favicon by providing it as an inline SVG image.
// Hat tip to Lea Verou! https://twitter.com/LeaVerou/status/1241619866475474946
return <Favicon emoji="🌈" />;
}
If you use either of these special props, you must include the data:
source in your content security policy’s img-src
, as these props use an inline image provided as a data URI.
Some libraries require you to put attributes on “special” elements in the DOM, most commonly either on the root <html>
element, or the <body>
element. Quilt provides an <HTMLAttributes>
component and useHTMLAttributes
hook for applying props to the <html>
element from within your React app, and <BodyAttributes>
/ useBodyAttributes
for applying props to the <body>
element:
import {
BodyAttributes,
HTMLAttributes,
useBodyAttributes,
useHTMLAttributes,
} from '@quilted/react-html';
// also available from '@quilted/quilt/html'
export function App() {
useHTMLAttributes({lang: 'en'});
useBodyAttributes({'data-page': 'my-page'});
// or...
return (
<>
<HTMLAttributes lang="en" />
<BodyAttributes data-page="my-page" />
</>
);
}
A common need in web applications is to reference some data that exists on the server. This could be data loaded from a database, or retrieved with a network call. However it is fetched, you typically use that data to impact the content you render — for example, to render a list of products fetched from a GraphQL API. If you want to render that content on the server, and then have it render on the client as well, the data will need to be sent from the server to the client.
Quilt provides a solution to this problem that works for web applications by rendering the data into your HTML document in a process we refer to as “serialization”. Specifically, Quilt places the data you need in <meta>
tags in the head of the document, serializing the data as JSON.
The @quilted/react-html
documentation outlines how to use the useSerialized()
hook, which Quilt provides for implementing server-to-client serialization. Quilt uses this hook internally for serializing GraphQL results and HTTP headers, so you may not need to use it yourself, but it’s nice to have it there for complex applications using Quilt!