Say Hello to the Inertia Head Component

Published on by

Say Hello to the Inertia Head Component image

With the newest release of Inertia.js comes a new component called "Inertia head." This new component allows you to update the <title> and <meta> tags inside the <head> tag of your HTML. Before this component, trying to change the <title> of your page, although not impossible, wasn't very easy. Not only can you do this with ease within your page component, but you can also take advantage of any props passed to your page.

Imagine being able to set your Open Graph tags dynamically or updating the page's title when your user is reading an article, or even changing the favicon; all of this is possible.

To demonstrate this new feature, let's start using my favorite Laravel starter kit Laravel Breeze.

Start by creating a new Laravel app.

laravel new inertia-head-demo

Once this is run, cd into your new project and run

composer require laravel/breeze --dev

followed by

PHP artisan breeze:install vue

Once this has run, you should see your devDependencies of your package.json have been updated and look like this.

"devDependencies": {
"@inertiajs/inertia": "^0.8.4",
"@inertiajs/inertia-vue3": "^0.3.5",
"@inertiajs/progress": "^0.2.4",
"@tailwindcss/forms": "^0.2.1",
"@vue/compiler-sfc": "^3.0.5",
"autoprefixer": "^10.2.4",
"axios": "^0.21",
"laravel-mix": "^6.0.6",
"lodash": "^4.17.19",
"postcss": "^8.2.13",
"postcss-import": "^14.0.1",
"tailwindcss": "^2.1.2",
"vue": "^3.0.5",
"vue-loader": "^16.1.2"
}

To take advantage of this <inertia-head>, we need to bump the version of @inertiajs/inertia, @inertiajs/inertia-vue3. While we are at it, we can also update @inertiajs/progress to the latest version, but this isn't required.

"devDependencies": {
"@inertiajs/inertia": "^0.9.1",
"@inertiajs/inertia-vue3": "^0.4.2",
"@inertiajs/progress": "^0.2.5", // optional
...
}

Next, let's install our JavaScript dependencies and build our assets and watch for changes.

npm install && npm run watch

Next, we want to edit our app layouts and add <inertia-head> tags. What we set here will be the "defaults" that we can override at the page level.

In Breeze, there are two layout components, Guest.vue located at resources/js/Layouts/Guest.vue and Authenticated.vue located at resources/js/Layouts/Authenticated. vue The Guest.vue layout gets used by all the auth views, and Authenticated.vue gets used once the user has authenticated and is viewing their dashboard. For this example, we will focus on the auth screens and the Guest.vue layout; add the following to Guest.vue layout anywhere in the <template> tags.

<inertia-head title="Inertia Head Demo" />

I am using Laravel Valet locally, so if I go and visit http://inertia-head-demo.test/login I should expect to see the title for that page to be "Inertia Head Demo," but visiting /login to check, the title will show "Laravel" or whatever your is in your .env setting for APP_NAME. The reason for that is there should only ever be one <title> tag on the page, and if there are more than one, the first one that appears on the page will take priority. If you check the app.blade.php file, you'll see this on line 8

<title>{{ config('app.name', 'Laravel') }}</title>

If you delete the above line and refresh the page, we should see the title we set in our layout.

Good stuff, right? Okay, let's take that next step. Open Login.vue and add a <inertia-head> tag to overwrite the default we set in the Guest.vue

<inertia-head title="Inertia Head Demo - Login" />

Now when you visit /login, you will see Inertia Head Demo - Login in your browser tab as the title.

Open Graph meta tags

Facebook and Twitter both allow you to customize what the preview for a URL looks like. You can read about Facebook's OG tags here and Twitter cards here.

Let's start by updating the default <inertia-head> component we added to Guest.vue add the following.

<inertia-head>
<title>Inertia Head Demo</title>
<meta type="description" content="Inertia Head Demo." />
<meta name="twitter:title" content="Inertia Head Demo" />
<meta name="twitter:site" content="@ninjaparade" />
<meta name="twitter:creator" content="@ninjaparade" />
<meta name="twitter:description" content="Inertia Head Demo." />
<meta name="twitter:card" content="summary_large_image" />
 
<meta property="og:url" content="http://inertia-head-demo.test" />
<meta property="og:title" content="Inertia Head Demo" />
<meta property="og:description" content="Inertia Head Demo" />
<meta property="og:type" content="website" />
<meta property="og:image" content="https://www.biography.com/.image/t_share/MTQ3NTI2OTA4NzY5MjE2MTI4/drake_photo_by_prince_williams_wireimage_getty_479503454.jpg" />
</inertia-head>

Now visit /login, and you should see this.

<head>
<title inertia="">Inertia Head Demo </title>
<meta type="description" content="Inertia Head Demo." inertia="" />
<meta property="og:url" content="http://inertia-head-demo.test" inertia="" />
<meta property="og:image" content="https://www.biography.com/.image/t_share/MTQ3NTI2OTA4NzY5MjE2MTI4/drake_photo_by_prince_williams_wireimage_getty_479503454.jpg" inertia="" />
<meta name="twitter:title" content="Inertia Head Demo." inertia="" />
<meta name="twitter:site" content="@ninjaparade" inertia="" />
<meta name="twitter:creator" content="@ninjaparade" inertia="" />
<meta name="twitter:description" content="Inertia Head Demo." inertia="" />
<meta name="twitter:card" content="summary_large_image" inertia="" />
<meta property="og:title" content="Inertia Head Demo." inertia="" />
<meta property="og:description" content="Inertia Head Demo." inertia="" />
<meta property="og:type" content="website" inertia="" />
</head>

You can see the OG Meta tags, followed by the title. The defaults are used here, and since we set the title in the <inertia-head> on our Login.vue page, we see Inertia removing the default title and using the one from our page component.

Now let's try to set the OG tags in our Login.vue component. I'm going to add this.

<inertia-head>
<title>Inertia Head Demo - Login</title>
<meta type="description" content="Inertia Head Demo - Login page." />
<meta name="twitter:title" content="Inertia Head Demo - Login page." />
<meta name="twitter:site" content="@ninjaparade" />
<meta name="twitter:creator" content="@ninjaparade" />
<meta name="twitter:description" content="Inertia Head Demo - Login page." />
<meta name="twitter:card" content="summary_large_image" />
 
<meta property="og:url" content="http://inertia-head-demo.test/login" />
<meta property="og:title" content="Inertia Head Demo - Login page." />
<meta property="og:description" content="Inertia Head Demo - Login page." />
<meta property="og:type" content="website" />
<meta property="og:image" content="https://www.biography.com/.image/t_share/MTQ3NTI2OTA4NzY5MjE2MTI4/drake_photo_by_prince_williams_wireimage_getty_479503454.jpg" />
</inertia-head>

Now refresh and visit /login... WHAT IS HAPPENING!?

<head>
...
<meta type="description" content="Inertia Head Demo." inertia="" />
<meta property="og:url" content="http://inertia-head-demo.test" inertia="" />
<meta property="og:image" content="https://www.biography.com/.image/t_share/MTQ3NTI2OTA4NzY5MjE2MTI4/drake_photo_by_prince_williams_wireimage_getty_479503454.jpg" inertia="" />
<meta name="twitter:title" content="Inertia Head Demo." inertia="" />
<meta name="twitter:site" content="@ninjaparade" inertia="" />
<meta name="twitter:creator" content="@ninjaparade" inertia="" />
<meta name="twitter:description" content="Inertia Head Demo." inertia="" />
<meta name="twitter:card" content="summary_large_image" inertia="" />
<meta type="description" content="Inertia Head Demo - Login page." inertia="" />
<meta name="twitter:title" content="Inertia Head Demo - Login page." inertia="" />
<meta name="twitter:site" content="@ninjaparade" inertia="" />
<meta name="twitter:creator" content="@ninjaparade" inertia="" />
<meta name="twitter:description" content="Inertia Head Demo - Login page." inertia="" />
<meta name="twitter:card" content="summary_large_image" inertia="" />
<meta property="og:url" content="http://inertia-head-demo.test" inertia="" />
<meta property="og:title" content="Inertia Head Demo - Login page." inertia="" />
<meta property="og:description" content="Inertia Head Demo - Login page." inertia="" />
<meta property="og:type" content="website" inertia="" />
<meta property="og:image" content="https://www.biography.com/.image/t_share/MTQ3NTI2OTA4NzY5MjE2MTI4/drake_photo_by_prince_williams_wireimage_getty_479503454.jpg" inertia="" />
<title inertia="">Inertia Head Demo - Login</title>
</head>

Our <head> tag now has duplicates of our meta tags; why is this happening? The <inertia-head> component will always ensure only one <title> tag. When it comes to the <meta> tags <inertia-head> is simply going to take the defaults and the <meta> tags from the Login.vue component and stack them, which is why you see them duplicated. Thankfully fixing this is pretty straightforward. We can tell <inertia-head> how to handle duplicates by adding a head-key property, ensuring the tag renders once.

So change the Guest.vue Inertia head to this.

<inertia-head>
<title>Inertia Head Demo</title>
<meta head-key="description" type="description" content="Inertia Head Demo." />
<meta head-key="twitter:title" name="twitter:title" content="Inertia Head Demo." />
<meta head-key="twitter:site" name="twitter:site" content="@ninjaparade" />
<meta head-key="twitter:creator" name="twitter:creator" content="@ninjaparade" />
<meta head-key="twitter:description" name="twitter:description" content="Inertia Head Demo." />
<meta head-key="twitter:card" name="twitter:card" content="summary_large_image" />
 
<meta head-key="og:url" property="og:url" content="http://inertia-head-demo.test" />
<meta head-key="og:title" property="og:title" content="Inertia Head Demo." />
<meta head-key="og:description" property="og:description" content="Inertia Head Demo." />
<meta head-key="og:type" property="og:type" content="website" />
<meta head-key="og:image" property="og:image" content="https://www.biography.com/.image/t_share/MTQ3NTI2OTA4NzY5MjE2MTI4/drake_photo_by_prince_williams_wireimage_getty_479503454.jpg" />
</inertia-head>

And change the <inertia-head> component in Login.vue to the following:

<inertia-head>
<title>Inertia Head Demo - Login</title>
<meta head-key="description" type="description" content="Inertia Head Demo - Login page." />
<meta head-key="twitter:title" name="twitter:title" content="Inertia Head Demo - Login page." />
<meta head-key="twitter:site" name="twitter:site" content="@ninjaparade" />
<meta head-key="twitter:creator" name="twitter:creator" content="@ninjaparade" />
<meta head-key="twitter:description" name="twitter:description" content="Inertia Head Demo - Login page." />
<meta head-key="twitter:card" name="twitter:card" content="summary_large_image" />
 
<meta head-key="og:url" property="og:url" content="http://inertia-head-demo.test/login" />
<meta head-key="og:title" property="og:title" content="Inertia Head Demo - Login page." />
<meta head-key="og:description" property="og:description" content="Inertia Head Demo - Login page." />
<meta head-key="og:type" property="og:type" content="website" />
<meta head-key="og:image" property="og:image" content="https://www.biography.com/.image/t_share/MTQ3NTI2OTA4NzY5MjE2MTI4/drake_photo_by_prince_williams_wireimage_getty_479503454.jpg" />
</inertia-head>

After updating that, recompile your assets, refresh, and you should see this:

<head>
...
<title inertia="">Inertia Head Demo - Login</title>
<meta type="description" content="Inertia Head Demo - Login page." inertia="description" />
<meta property="og:url" content="http://inertia-head-demo.test" inertia="og:url" />
<meta property="og:image" content="https://www.biography.com/.image/t_share/MTQ3NTI2OTA4NzY5MjE2MTI4/drake_photo_by_prince_williams_wireimage_getty_479503454.jpg" inertia="og:image" />
<meta name="twitter:title" content="Inertia Head Demo - Login page." inertia="twitter:title" />
<meta name="twitter:site" content="@ninjaparade" inertia="twitter:site" />
<meta name="twitter:creator" content="@ninjaparade" inertia="twitter:creator" />
<meta name="twitter:description" content="Inertia Head Demo - Login page." inertia="twitter:description" />
<meta name="twitter:card" content="summary_large_image" inertia="twitter:card" />
<meta property="og:title" content="Inertia Head Demo - Login page." inertia="og:title" />
<meta property="og:description" content="Inertia Head Demo - Login page." inertia="og:description" />
<meta property="og:type" content="website" inertia="og:type" />
</head>

That's it! There is more to discuss about <inertia-head> and where it shines when paired with an upcoming feature to provide server-side rendering for Inertia. SSR for Inertia is ready to be used and is currently powering the Inertia.js website, but documentation on how to get this working on Laravel Forge and Heroku are currently available to Inertia sponsors.

Thanks for reading, and feel free to reach out on Twitter if you got any questions.

Yaz Jallad photo

Yaz is a full stack developer with a passion for everything Laravel, Vue.js, Tailwind CSS and Inertia.js.

Cube

Laravel Newsletter

Join 40k+ other developers and never miss out on new tips, tutorials, and more.

image
Larafast: Laravel SaaS Starter Kit

Larafast is a Laravel SaaS Starter Kit with ready-to-go features for Payments, Auth, Admin, Blog, SEO, and beautiful themes.

Visit Larafast: Laravel SaaS Starter Kit
Laravel Forge logo

Laravel Forge

Easily create and manage your servers and deploy your Laravel applications in seconds.

Laravel Forge
Tinkerwell logo

Tinkerwell

The must-have code runner for Laravel developers. Tinker with AI, autocompletion and instant feedback on local and production environments.

Tinkerwell
No Compromises logo

No Compromises

Joel and Aaron, the two seasoned devs from the No Compromises podcast, are now available to hire for your Laravel project. ⬧ Flat rate of $7500/mo. ⬧ No lengthy sales process. ⬧ No contracts. ⬧ 100% money back guarantee.

No Compromises
Kirschbaum logo

Kirschbaum

Providing innovation and stability to ensure your web application succeeds.

Kirschbaum
Shift logo

Shift

Running an old Laravel version? Instant, automated Laravel upgrades and code modernization to keep your applications fresh.

Shift
Bacancy logo

Bacancy

Supercharge your project with a seasoned Laravel developer with 4-6 years of experience for just $2500/month. Get 160 hours of dedicated expertise & a risk-free 15-day trial. Schedule a call now!

Bacancy
Lucky Media logo

Lucky Media

Bespoke software solutions built for your business. We ♥ Laravel

Lucky Media
Lunar: Laravel E-Commerce logo

Lunar: Laravel E-Commerce

E-Commerce for Laravel. An open-source package that brings the power of modern headless e-commerce functionality to Laravel.

Lunar: Laravel E-Commerce
LaraJobs logo

LaraJobs

The official Laravel job board

LaraJobs
Larafast: Laravel SaaS Starter Kit logo

Larafast: Laravel SaaS Starter Kit

Larafast is a Laravel SaaS Starter Kit with ready-to-go features for Payments, Auth, Admin, Blog, SEO, and beautiful themes. Available with VILT and TALL stacks.

Larafast: Laravel SaaS Starter Kit
SaaSykit: Laravel SaaS Starter Kit logo

SaaSykit: Laravel SaaS Starter Kit

SaaSykit is a Laravel SaaS Starter Kit that comes with all features required to run a modern SaaS. Payments, Beautiful Checkout, Admin Panel, User dashboard, Auth, Ready Components, Stats, Blog, Docs and more.

SaaSykit: Laravel SaaS Starter Kit
Rector logo

Rector

Your partner for seamless Laravel upgrades, cutting costs, and accelerating innovation for successful companies

Rector

The latest

View all →
Anonymous Event Broadcasting in Laravel 11.5 image

Anonymous Event Broadcasting in Laravel 11.5

Read article
Microsoft Clarity Integration for Laravel image

Microsoft Clarity Integration for Laravel

Read article
Apply Dynamic Filters to Eloquent Models with the Filterable Package image

Apply Dynamic Filters to Eloquent Models with the Filterable Package

Read article
Property Hooks Get Closer to Becoming a Reality in PHP 8.4 image

Property Hooks Get Closer to Becoming a Reality in PHP 8.4

Read article
Asserting Exceptions in Laravel Tests image

Asserting Exceptions in Laravel Tests

Read article
Reversible Form Prompts and a New Exceptions Facade in Laravel 11.4 image

Reversible Form Prompts and a New Exceptions Facade in Laravel 11.4

Read article