Skip to content

Commit 958cf54

Browse files
committed
docs(solid-meta): add useHead reference
1 parent e53d4f0 commit 958cf54

3 files changed

Lines changed: 255 additions & 6 deletions

File tree

src/routes/solid-meta/getting-started/installation-and-setup.mdx

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -33,11 +33,12 @@ To get started, install using your preferred package manager.
3333

3434
1. Wrap your application with [`<MetaProvider />`](/solid-meta/reference/meta/metaprovider)
3535
2. To include head tags within your application, render any of the following:
36-
1. [`<Title />`](/solid-meta/reference/meta/title): Adds the `title` of the page.
37-
2. [`<Meta />`](/solid-meta/reference/meta/meta): Adds extra metadata to the page.
38-
3. [`<Style />`](/solid-meta/reference/meta/style): Adds a `style` element to the page.
39-
4. [`<Link />`](/solid-meta/reference/meta/link): Specifies a relationship between the page and an external resource.
40-
5. [`<Base />`](/solid-meta/reference/meta/base): Specifies the base URL for all relative URLs in the document.
36+
1. [`<Title />`](/solid-meta/reference/meta/title): Adds the `title` of the page.
37+
2. [`<Meta />`](/solid-meta/reference/meta/meta): Adds extra metadata to the page.
38+
3. [`<Style />`](/solid-meta/reference/meta/style): Adds a `style` element to the page.
39+
4. [`<Link />`](/solid-meta/reference/meta/link): Specifies a relationship between the page and an external resource.
40+
5. [`<Base />`](/solid-meta/reference/meta/base): Specifies the base URL for all relative URLs in the document.
41+
6. [`useHead`](/solid-meta/reference/meta/use-head): Inserts arbitrary head tags when a dedicated component does not exist.
4142
- These components can be used multiple times within the application.
4243
3. If using Solid on the server with JSX, no additional configuration is required.
4344

src/routes/solid-meta/reference/meta/data.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
"meta.mdx",
77
"style.mdx",
88
"base.mdx",
9-
"metaprovider.mdx"
9+
"metaprovider.mdx",
10+
"use-head.mdx"
1011
]
1112
}
Lines changed: 247 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,247 @@
1+
---
2+
title: useHead
3+
order: 7
4+
use_cases: >-
5+
custom head tags, scripts, json-ld, arbitrary head elements, dynamic metadata,
6+
ssr head management
7+
tags:
8+
- usehead
9+
- head
10+
- meta
11+
- script
12+
- json-ld
13+
- ssr
14+
version: '1.0'
15+
description: >-
16+
useHead inserts custom elements into document head with fine-grained control,
17+
including scripts and JSON-LD, while staying SSR-ready.
18+
---
19+
20+
`useHead` registers a custom head tag with the nearest [`MetaProvider`](/solid-meta/reference/meta/metaprovider).
21+
It is the low-level API used by the head components.
22+
It must be called under a `MetaProvider`, or it throws.
23+
24+
Use it when you need a tag that does not have a dedicated component or when you need full control over closing tags and escaping.
25+
26+
## When to use useHead
27+
28+
- Insert tags without built-in components, such as `script` and `noscript`.
29+
- Control SSR output with `setting.close` and `setting.escape`.
30+
- Inject per-page structured data like JSON-LD.
31+
- Reuse an existing element via `ref`.
32+
33+
## Prefer components when possible
34+
35+
Use the dedicated components when they fit your use case:
36+
37+
- [`<Title />`](/solid-meta/reference/meta/title) for page titles.
38+
- [`<Meta />`](/solid-meta/reference/meta/meta) for metadata.
39+
- [`<Link />`](/solid-meta/reference/meta/link) for external resources.
40+
- [`<Style />`](/solid-meta/reference/meta/style) for inline styles.
41+
- [`<Base />`](/solid-meta/reference/meta/base) for base URLs.
42+
43+
They provide clearer intent and sensible defaults.
44+
45+
## Import
46+
47+
```ts
48+
import { useHead } from "@solidjs/meta";
49+
```
50+
51+
## Type
52+
53+
```ts
54+
type TagDescription = {
55+
tag: string;
56+
props: Record<string, unknown>;
57+
setting?: {
58+
close?: boolean;
59+
escape?: boolean;
60+
};
61+
id: string;
62+
name?: string;
63+
ref?: Element;
64+
};
65+
66+
function useHead(tag: TagDescription): void;
67+
```
68+
69+
## Parameters
70+
71+
### `tag`
72+
73+
- **Type:** `string`
74+
- **Required:** Yes
75+
76+
The tag name to render in `<head>`, such as `script`, `meta`, or `title`.
77+
78+
### `props`
79+
80+
- **Type:** `Record<string, unknown>`
81+
- **Required:** Yes
82+
83+
The attributes and properties applied to the element.
84+
85+
#### `props.children`
86+
87+
When provided, `children` becomes the element content for tags like `title`, `style`, or `script`.
88+
On the server, arrays of strings are concatenated without commas.
89+
If `setting.close` is not enabled, `children` is not rendered during SSR.
90+
91+
### `setting`
92+
93+
- **Type:** `{ close?: boolean; escape?: boolean }`
94+
- **Required:** No
95+
96+
SSR-only rendering options for the tag contents.
97+
98+
#### `setting.close`
99+
100+
- **Type:** `boolean`
101+
- **Required:** No
102+
103+
When `true`, the server renders a closing tag and includes `children`.
104+
Use this for tags that cannot be self-closing, such as `script`, `style`, and `title`.
105+
106+
#### `setting.escape`
107+
108+
- **Type:** `boolean`
109+
- **Required:** No
110+
111+
When `true`, the server HTML-escapes `children`.
112+
If omitted or `false`, `children` is rendered as raw HTML.
113+
114+
### `id`
115+
116+
- **Type:** `string`
117+
- **Required:** Yes
118+
119+
A stable identifier used to match server-rendered tags during hydration.
120+
Use a consistent `id` for the lifetime of the component.
121+
122+
### `name`
123+
124+
- **Type:** `string`
125+
- **Required:** No
126+
127+
An optional label for the tag.
128+
For `meta` tags, it typically mirrors `props.name` or `props.property`.
129+
130+
### `ref`
131+
132+
- **Type:** `Element`
133+
- **Required:** No
134+
135+
An existing element to reuse instead of creating a new one.
136+
This is usually managed internally.
137+
138+
## Return value
139+
140+
`useHead` does not return a value.
141+
142+
## Examples
143+
144+
### Simple custom tag
145+
146+
```tsx
147+
import { useHead } from "@solidjs/meta";
148+
149+
useHead({
150+
tag: "link",
151+
id: "rss-feed",
152+
props: {
153+
rel: "alternate",
154+
type: "application/rss+xml",
155+
title: "Solid RSS",
156+
href: "/rss.xml",
157+
},
158+
});
159+
```
160+
161+
### JSON-LD per page (script with `close` and `escape`)
162+
163+
```tsx
164+
import { useHead } from "@solidjs/meta";
165+
166+
const jsonLD = JSON.stringify({
167+
"@context": "https://schema.org",
168+
"@type": "WebSite",
169+
name: "Solid Docs",
170+
url: "https://docs.solidjs.com/",
171+
});
172+
173+
useHead({
174+
tag: "script",
175+
setting: { close: true, escape: false },
176+
id: "schema-home",
177+
props: {
178+
type: "application/ld+json",
179+
children: jsonLD,
180+
},
181+
});
182+
```
183+
184+
### Reactive updates
185+
186+
```tsx
187+
import { createSignal } from "solid-js";
188+
import { useHead } from "@solidjs/meta";
189+
190+
const [pageTitle, setPageTitle] = createSignal("Getting started");
191+
192+
useHead({
193+
tag: "title",
194+
setting: { close: true, escape: true },
195+
id: "page-title",
196+
props: {
197+
get children() {
198+
return `${pageTitle()} | Solid`;
199+
},
200+
},
201+
});
202+
```
203+
204+
## Notes
205+
206+
### SSR and hydration
207+
208+
On the server, tags are collected and rendered into `<head>`.
209+
During hydration, tags with matching `id` values are reused.
210+
On client-only renders, existing server tags are removed and replaced.
211+
212+
### Dedupe and idempotency
213+
214+
For `title` and `meta`, only the most recent tag with the same key is kept.
215+
The key is derived from the tag name and selected attributes.
216+
For `meta`, the key uses `name` (or `property`), `http-equiv`, `content`, `charset`, and `media`.
217+
For `title`, the key does not include any attributes.
218+
Other tag types are not deduped.
219+
The `id` does not control deduping.
220+
It ensures hydration can reuse the same element instead of inserting a duplicate.
221+
222+
### Reactive updates and cleanup
223+
224+
`useHead` runs inside a render effect.
225+
If your tag description reads reactive values, the tag updates when those values change.
226+
When the component unmounts, the tag is removed and any previous cascading tag is restored.
227+
228+
### Security and escaping
229+
230+
Use `setting.escape: true` when inserting untrusted content.
231+
Setting `escape: false` renders raw HTML and can create XSS risks.
232+
Only use `escape: false` with trusted, pre-serialized strings such as JSON-LD.
233+
234+
### Best practices
235+
236+
Use stable, unique `id` values to avoid duplicates.
237+
Prefer the dedicated head components when they meet your needs.
238+
Avoid inserting multiple tags that represent the same metadata unless you intend to override.
239+
240+
## Related
241+
242+
- [`<MetaProvider />`](/solid-meta/reference/meta/metaprovider)
243+
- [`<Title />`](/solid-meta/reference/meta/title)
244+
- [`<Meta />`](/solid-meta/reference/meta/meta)
245+
- [`<Link />`](/solid-meta/reference/meta/link)
246+
- [`<Style />`](/solid-meta/reference/meta/style)
247+
- [`<Base />`](/solid-meta/reference/meta/base)

0 commit comments

Comments
 (0)