or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

app-lifecycle.mdconfiguration.mdcore.mddata-fetching.mdhead.mdindex.mdmodule-dev.mdnavigation.mdperformance.mdssr.mdstate.md

head.mddocs/

0

# Head Management

1

2

Document head management with reactive updates, SEO optimization, and server-side rendering support. Nuxt provides comprehensive utilities for managing meta tags, titles, and other head elements with full SSR support.

3

4

## Capabilities

5

6

### Basic Head Management

7

8

Manage document head elements with reactive updates.

9

10

```typescript { .api }

11

/**

12

* Manage document head with reactive updates

13

* @param meta - Meta object or reactive reference to meta object

14

*/

15

function useHead(meta: MaybeComputedRef<MetaObject>): void;

16

17

/**

18

* Safe version of useHead that sanitizes input

19

* @param meta - Meta object or reactive reference to meta object

20

*/

21

function useHeadSafe(meta: MaybeComputedRef<MetaObject>): void;

22

23

/**

24

* Inject head client directly for advanced usage

25

* @returns HeadClient instance

26

*/

27

function injectHead(): HeadClient;

28

29

interface MetaObject {

30

/** Page title */

31

title?: MaybeComputedRef<string>;

32

/** Title template for dynamic titles */

33

titleTemplate?: MaybeComputedRef<string | ((title?: string) => string)>;

34

/** Meta tags */

35

meta?: MaybeComputedRef<MetaObjectRaw[]>;

36

/** Link tags */

37

link?: MaybeComputedRef<LinkObject[]>;

38

/** Style tags */

39

style?: MaybeComputedRef<StyleObject[]>;

40

/** Script tags */

41

script?: MaybeComputedRef<ScriptObject[]>;

42

/** Noscript tags */

43

noscript?: MaybeComputedRef<NoscriptObject[]>;

44

/** Base tag */

45

base?: MaybeComputedRef<BaseObject>;

46

/** Body attributes */

47

bodyAttrs?: MaybeComputedRef<Record<string, any>>;

48

/** HTML attributes */

49

htmlAttrs?: MaybeComputedRef<Record<string, any>>;

50

}

51

52

interface MetaObjectRaw {

53

name?: string;

54

property?: string;

55

"http-equiv"?: string;

56

content?: string;

57

charset?: string;

58

[key: string]: any;

59

}

60

```

61

62

**Usage Examples:**

63

64

```typescript

65

// Basic title and meta

66

useHead({

67

title: "My Page Title",

68

meta: [

69

{ name: "description", content: "Page description" },

70

{ name: "keywords", content: "nuxt, vue, ssr" }

71

]

72

});

73

74

// Reactive head management

75

const pageTitle = ref("Dynamic Title");

76

const pageDescription = ref("Dynamic description");

77

78

useHead({

79

title: pageTitle,

80

meta: [

81

{ name: "description", content: pageDescription }

82

]

83

});

84

85

// Title template

86

useHead({

87

titleTemplate: (title) => title ? `${title} - My App` : "My App"

88

});

89

90

// Complex head configuration

91

useHead({

92

title: "Article Title",

93

meta: [

94

{ name: "description", content: "Article description" },

95

{ name: "author", content: "John Doe" },

96

{ name: "robots", content: "index,follow" },

97

{ property: "og:title", content: "Article Title" },

98

{ property: "og:description", content: "Article description" },

99

{ property: "og:image", content: "/images/article.jpg" },

100

{ property: "og:type", content: "article" },

101

{ name: "twitter:card", content: "summary_large_image" }

102

],

103

link: [

104

{ rel: "canonical", href: "https://example.com/article" },

105

{ rel: "alternate", hreflang: "es", href: "https://example.com/es/article" }

106

]

107

});

108

109

// Safe head management (auto-sanitized)

110

useHeadSafe({

111

title: userInput, // Will be sanitized

112

meta: [

113

{ name: "description", content: userDescription } // Will be sanitized

114

]

115

});

116

```

117

118

### SEO Meta Management

119

120

Specialized utilities for SEO-focused meta tag management.

121

122

```typescript { .api }

123

/**

124

* Manage SEO-specific meta tags

125

* @param meta - SEO meta object

126

*/

127

function useSeoMeta(meta: MaybeComputedRef<SeoMetaObject>): void;

128

129

interface SeoMetaObject {

130

/** Page title */

131

title?: MaybeComputedRef<string>;

132

/** Meta description */

133

description?: MaybeComputedRef<string>;

134

/** Keywords */

135

keywords?: MaybeComputedRef<string | string[]>;

136

/** Author */

137

author?: MaybeComputedRef<string>;

138

/** Robots directive */

139

robots?: MaybeComputedRef<string>;

140

/** Copyright */

141

copyright?: MaybeComputedRef<string>;

142

/** Language */

143

language?: MaybeComputedRef<string>;

144

/** Theme color */

145

themeColor?: MaybeComputedRef<string>;

146

/** Color scheme */

147

colorScheme?: MaybeComputedRef<string>;

148

/** Viewport */

149

viewport?: MaybeComputedRef<string>;

150

/** Canonical URL */

151

canonical?: MaybeComputedRef<string>;

152

153

// Open Graph

154

/** OG title */

155

ogTitle?: MaybeComputedRef<string>;

156

/** OG description */

157

ogDescription?: MaybeComputedRef<string>;

158

/** OG image */

159

ogImage?: MaybeComputedRef<string | OgImageObject>;

160

/** OG URL */

161

ogUrl?: MaybeComputedRef<string>;

162

/** OG type */

163

ogType?: MaybeComputedRef<string>;

164

/** OG site name */

165

ogSiteName?: MaybeComputedRef<string>;

166

/** OG locale */

167

ogLocale?: MaybeComputedRef<string>;

168

169

// Twitter

170

/** Twitter card type */

171

twitterCard?: MaybeComputedRef<string>;

172

/** Twitter title */

173

twitterTitle?: MaybeComputedRef<string>;

174

/** Twitter description */

175

twitterDescription?: MaybeComputedRef<string>;

176

/** Twitter image */

177

twitterImage?: MaybeComputedRef<string>;

178

/** Twitter site */

179

twitterSite?: MaybeComputedRef<string>;

180

/** Twitter creator */

181

twitterCreator?: MaybeComputedRef<string>;

182

}

183

184

interface OgImageObject {

185

url: string;

186

width?: number;

187

height?: number;

188

alt?: string;

189

type?: string;

190

}

191

```

192

193

**Usage Examples:**

194

195

```typescript

196

// Basic SEO meta

197

useSeoMeta({

198

title: "My Page",

199

description: "Comprehensive description of my page content",

200

keywords: ["nuxt", "vue", "ssr", "framework"],

201

author: "John Doe",

202

robots: "index,follow"

203

});

204

205

// Social media optimization

206

useSeoMeta({

207

title: "Amazing Article",

208

description: "This article will change your perspective on web development",

209

210

// Open Graph

211

ogTitle: "Amazing Article - My Blog",

212

ogDescription: "This article will change your perspective on web development",

213

ogImage: {

214

url: "https://example.com/images/article-cover.jpg",

215

width: 1200,

216

height: 630,

217

alt: "Article cover image"

218

},

219

ogUrl: "https://example.com/articles/amazing-article",

220

ogType: "article",

221

ogSiteName: "My Blog",

222

ogLocale: "en_US",

223

224

// Twitter

225

twitterCard: "summary_large_image",

226

twitterTitle: "Amazing Article",

227

twitterDescription: "This article will change your perspective",

228

twitterImage: "https://example.com/images/article-cover.jpg",

229

twitterSite: "@myblog",

230

twitterCreator: "@johndoe"

231

});

232

233

// Reactive SEO meta

234

const article = ref({

235

title: "Dynamic Article",

236

description: "Dynamic description",

237

image: "/images/default.jpg"

238

});

239

240

useSeoMeta({

241

title: () => article.value.title,

242

description: () => article.value.description,

243

ogImage: () => article.value.image,

244

twitterImage: () => article.value.image

245

});

246

247

// E-commerce product SEO

248

const product = await useFetch(`/api/products/${route.params.id}`);

249

250

useSeoMeta({

251

title: () => `${product.data.value?.name} - Shop`,

252

description: () => product.data.value?.description,

253

keywords: () => product.data.value?.tags,

254

ogType: "product",

255

ogImage: () => product.data.value?.images[0],

256

ogPrice: () => product.data.value?.price,

257

ogCurrency: "USD"

258

});

259

```

260

261

### Server-Side Head Management

262

263

Server-only head management utilities.

264

265

```typescript { .api }

266

/**

267

* Server-only head management

268

* @param meta - Meta object for server-side rendering

269

*/

270

function useServerHead(meta: MaybeComputedRef<MetaObject>): void;

271

272

/**

273

* Safe server-only head management

274

* @param meta - Meta object for server-side rendering

275

*/

276

function useServerHeadSafe(meta: MaybeComputedRef<MetaObject>): void;

277

278

/**

279

* Server-only SEO meta management

280

* @param meta - SEO meta object for server-side rendering

281

*/

282

function useServerSeoMeta(meta: MaybeComputedRef<SeoMetaObject>): void;

283

```

284

285

**Usage Examples:**

286

287

```typescript

288

// Server-only head management

289

if (process.server) {

290

useServerHead({

291

script: [

292

{

293

innerHTML: `

294

window.serverData = ${JSON.stringify(serverData)};

295

`

296

}

297

]

298

});

299

}

300

301

// Server-side SEO optimization

302

useServerSeoMeta({

303

title: () => `${pageData.title} - ${siteName}`,

304

description: () => pageData.description,

305

canonical: () => `${baseUrl}${route.path}`,

306

307

// Generate structured data on server

308

script: [

309

{

310

type: "application/ld+json",

311

innerHTML: JSON.stringify({

312

"@context": "https://schema.org",

313

"@type": "Article",

314

"headline": pageData.title,

315

"description": pageData.description,

316

"author": pageData.author,

317

"datePublished": pageData.publishedAt

318

})

319

}

320

]

321

});

322

323

// Server-side analytics

324

useServerHead({

325

script: [

326

{

327

src: "https://www.googletagmanager.com/gtag/js?id=GA_MEASUREMENT_ID",

328

async: true

329

},

330

{

331

innerHTML: `

332

window.dataLayer = window.dataLayer || [];

333

function gtag(){dataLayer.push(arguments);}

334

gtag('js', new Date());

335

gtag('config', 'GA_MEASUREMENT_ID');

336

`

337

}

338

]

339

});

340

```

341

342

### Advanced Head Management Patterns

343

344

```typescript

345

// Conditional head management

346

const isDarkMode = useCookie("theme", { default: () => "light" });

347

348

useHead({

349

htmlAttrs: {

350

"data-theme": isDarkMode

351

},

352

meta: [

353

{

354

name: "theme-color",

355

content: () => isDarkMode.value === "dark" ? "#1a1a1a" : "#ffffff"

356

}

357

]

358

});

359

360

// Localized head management

361

const { locale, t } = useI18n();

362

363

useHead({

364

htmlAttrs: {

365

lang: locale

366

},

367

title: () => t("page.title"),

368

meta: [

369

{ name: "description", content: () => t("page.description") },

370

{ property: "og:locale", content: locale }

371

]

372

});

373

374

// Progressive enhancement

375

const supportsWebP = ref(false);

376

377

onMounted(async () => {

378

supportsWebP.value = await checkWebPSupport();

379

});

380

381

useHead({

382

link: [

383

{

384

rel: "preload",

385

as: "image",

386

href: () => supportsWebP.value ? "/hero.webp" : "/hero.jpg"

387

}

388

]

389

});

390

391

// Performance optimization

392

useHead({

393

link: [

394

// DNS prefetch

395

{ rel: "dns-prefetch", href: "//fonts.googleapis.com" },

396

{ rel: "dns-prefetch", href: "//api.example.com" },

397

398

// Preconnect

399

{ rel: "preconnect", href: "https://fonts.gstatic.com", crossorigin: "" },

400

401

// Resource hints

402

{ rel: "prefetch", href: "/next-page" },

403

{ rel: "preload", href: "/critical.css", as: "style" },

404

{ rel: "preload", href: "/hero.jpg", as: "image" }

405

]

406

});

407

408

// Error page head

409

const error = useError();

410

411

watch(error, (newError) => {

412

if (newError) {

413

useHead({

414

title: `Error ${newError.statusCode}`,

415

meta: [

416

{ name: "robots", content: "noindex,nofollow" }

417

]

418

});

419

}

420

});

421

```

422

423

### Dynamic Script and Style Management

424

425

```typescript

426

// Dynamic script loading

427

const loadGoogleMaps = ref(false);

428

429

useHead({

430

script: [

431

{

432

src: "https://maps.googleapis.com/maps/api/js?key=YOUR_API_KEY",

433

async: true,

434

onload: "window.initMap()",

435

condition: () => loadGoogleMaps.value

436

}

437

]

438

});

439

440

// Conditional styles

441

const isHighContrast = useCookie("high-contrast", { default: () => false });

442

443

useHead({

444

style: [

445

{

446

innerHTML: `

447

:root {

448

--text-color: ${isHighContrast.value ? "#000" : "#333"};

449

--bg-color: ${isHighContrast.value ? "#fff" : "#f5f5f5"};

450

}

451

`

452

}

453

]

454

});

455

456

// Third-party integrations

457

const enableAnalytics = ref(true);

458

459

useHead({

460

script: [

461

{

462

src: "https://www.googletagmanager.com/gtag/js?id=GA_ID",

463

async: true,

464

condition: () => enableAnalytics.value

465

},

466

{

467

innerHTML: `

468

window.dataLayer = window.dataLayer || [];

469

function gtag(){dataLayer.push(arguments);}

470

gtag('js', new Date());

471

gtag('config', 'GA_ID');

472

`,

473

condition: () => enableAnalytics.value

474

}

475

]

476

});

477

```

478

479

## Types

480

481

```typescript { .api }

482

type MaybeComputedRef<T> = T | Ref<T> | ComputedRef<T> | (() => T);

483

484

interface HeadClient {

485

push(input: MetaObject): ActiveHeadEntry;

486

resolveTags(): HeadTag[];

487

}

488

489

interface ActiveHeadEntry {

490

dispose(): void;

491

patch(input: MetaObject): void;

492

}

493

494

interface HeadTag {

495

tag: string;

496

attrs: Record<string, any>;

497

innerHTML?: string;

498

textContent?: string;

499

}

500

501

interface LinkObject {

502

rel?: string;

503

href?: string;

504

type?: string;

505

media?: string;

506

sizes?: string;

507

color?: string;

508

title?: string;

509

as?: string;

510

crossorigin?: string;

511

referrerpolicy?: string;

512

integrity?: string;

513

hreflang?: string;

514

[key: string]: any;

515

}

516

517

interface StyleObject {

518

innerHTML?: string;

519

textContent?: string;

520

media?: string;

521

type?: string;

522

[key: string]: any;

523

}

524

525

interface ScriptObject {

526

src?: string;

527

innerHTML?: string;

528

textContent?: string;

529

type?: string;

530

async?: boolean;

531

defer?: boolean;

532

crossorigin?: string;

533

integrity?: string;

534

nomodule?: boolean;

535

nonce?: string;

536

referrerpolicy?: string;

537

onload?: string;

538

onerror?: string;

539

condition?: () => boolean;

540

[key: string]: any;

541

}

542

543

interface NoscriptObject {

544

innerHTML?: string;

545

textContent?: string;

546

[key: string]: any;

547

}

548

549

interface BaseObject {

550

href?: string;

551

target?: string;

552

[key: string]: any;

553

}

554

```