Example <inertia-head> code

Getting started with <inertia-head>

Published June 8th, 2021

Update 23rd July 2021: @inertiajs/inertia 0.10.0 changes the way the <inertia-link> and <inertia-head> components are used. Find out more...


The first time I set up an Inertia project I stuck with what I knew: Vue 2, even though Inertia comes with a Vue 3 adapter. As part of the Inertia Vue 2 adapter, the third-party Vue Meta was used. Essentially this library allowed you to create add a metaInfo property to your Vue component to update the app’s metadata view-by-view. However, Vue Meta is still not ready for Vue 3.

This week, the Inertia team announced the <inertia-head> component, a first-party feature of Inertia that replaces the previously-used Vue Meta.

Before you get started, to use <inertia-head>, you’ll need to be running the correct breed:

I’ve got it all up and running using [email protected] and [email protected]

Before you go on, this post assumes you already have your Inertia app up and running and understand how its ecosystem works.

The basics

The <inertia-head> component is added globally to your Inertia app – you can use it in any of your Views.

All you need to do is include the component in your view, and include any of the properties you want to have injected in to the document’s <head>:

<template>
    <div>
        <inertia-head>
            <title>Update your profile</title>
        </inertia-head>
        <!-- ... -->
    </div>
</template>
<script>
export default {
    // ...
}
</script>

It just plops in to your component’s template, and the <inertia-head> component does the rest.

It could be as simple as the <title>, or could be a complete set of description and OG metadata – what you include really depends on your app.

Make sure you remove the <title> from your template

Your document can only include one <title> in your <head>.

Your initial template (such as app.blade.php) may already have one set:

<head>
    <!-- ... -->
    <title>app.blade.php title tag</title>
    <!-- ... -->
</head>

When using <inertia-head>, the component will output a title tag if you pass it one - this means your rendered page may actually have two title tags:

<head>
    <!-- ... -->
    <title>app.blade.php title tag</title>
    <!-- ... -->
    <title>Inertia generated title tag</title>
    <!-- ... -->
</head>

Your browser will only use the first <title> tag for displaying the title to the user, and the <inertia-head> won’t update the existing <title> attribute from your template.

To overcome this, you need to remove your <title> tag from your core template - such as your app.blade.php file, and rely on Inertia for generating the <title> markup for your app in all views.

Add the <inertia-head> to all of your views

Now that you have removed the <title> from your template, make sure you go through and add the <inertia-head> component to all of your views.

If you miss one, your page will miss injecting the <head> content – and if you’re updating the <title>, for example, will become title-less.

Unless… you set a default… keep reading.

Cascade like a waterfall

The <inertia-head> component is set up to cascade from your views down to your core app.

This means that in your app’s layout (or as a site-wide component – check the docs for that) you can set default <head> content that appears on all views. This is treated as the default, and then whatever you include in your views will be merged on top of the defaults.

If your default has:

  • <title> of “Portal”

When you access a view that does not have its own <inertia-head> component, the defaults (as above) will be rendered out to the <head> -  handy for setting a default title on all views of your app without including the component explicitly in each view.

However, take note that while there is only one <title> per page, other tags could be replicated if you have defaults and view-level tags. Let’s say you have a default meta “description”, and then a view-level “description”.

That would output:

<meta name="description" content="My default description">
<meta name="description" content="My update profile description">

Not really ideal, right? The <inertia-head> component comes with ability to key your tags within the component using the head-key property.

In your AppLayout.vue, you may have:

<inertia-head>
    <title>Default Title</title>
    <meta head-key="description" name="description" content="My default description">
</inertia-head>

And in your ShowProfile.vue, you could have:

<inertia-head>
    <title>Update your profile</title>
    <meta head-key="description" name="description" content="My update profile description">
</inertia-head>

The head-key property matches the two “description” tags, and overwrites the defaults based on the key provided. Pretty neat, right?

You can bind props to the content within <inertia-head>

Remember too that you can also bind props to your <head> tags – really great for customising titles to include a reference to the view’s data (or if you’re using centralised language stores, with language coming from variables and not hard-coded in each component).

<inertia-head>
    <title>Update your profile, {{ $page.props.user.name_first }}</title>
</inertia-head>

This is such a welcome and easy-to-use add-on to the Inertia ecosystem – and removing a dependency is an added bonus.

And as always, don’t forget to check out the Inertia Title and Meta documentation for full details on all of the features of <inertia-head>.

You may be interested in...