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.

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
Laravel Idea for PhpStorm logo

Laravel Idea for PhpStorm

Ultimate PhpStorm plugin for Laravel developers, delivering lightning-fast code completion, intelligent navigation, and powerful generation tools to supercharge productivity.

Laravel Idea for PhpStorm
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

Get Lucky Now - the ideal choice for Laravel Development, with over a decade of experience!

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
SaaSykit: Laravel SaaS Starter Kit logo

SaaSykit: Laravel SaaS Starter Kit

SaaSykit is a Multi-tenant 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
Supercharge Your SaaS Development with FilamentFlow: The Ultimate Laravel Filament Boilerplate logo

Supercharge Your SaaS Development with FilamentFlow: The Ultimate Laravel Filament Boilerplate

Build your SaaS application in hours. Out-of-the-box multi-tenancy and seamless Stripe integration. Supports subscriptions and one-time purchases, allowing you to focus on building and creating without repetitive setup tasks.

Supercharge Your SaaS Development with FilamentFlow: The Ultimate Laravel Filament Boilerplate
JetShip - Laravel Starter Kit logo

JetShip - Laravel Starter Kit

A Laravel SaaS Boilerplate and a starter kit built on the TALL stack. It includes authentication, payments, admin panels, and more. Launch scalable apps fast with clean code, seamless deployment, and custom branding.

JetShip - Laravel Starter Kit
Rector logo

Rector

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

Rector
MongoDB logo

MongoDB

Enhance your PHP applications with the powerful integration of MongoDB and Laravel, empowering developers to build applications with ease and efficiency. Support transactional, search, analytics and mobile use cases while using the familiar Eloquent APIs. Discover how MongoDB's flexible, modern database can transform your Laravel applications.

MongoDB

The latest

View all →
Streamlining Route Parameters in Laravel Using URL Defaults image

Streamlining Route Parameters in Laravel Using URL Defaults

Read article
Flexible Docker Images with PHP INI Environment Variables image

Flexible Docker Images with PHP INI Environment Variables

Read article
Dynamic Form Validation in Laravel with prohibited_if image

Dynamic Form Validation in Laravel with prohibited_if

Read article
Add Approvals to Your Laravel Application image

Add Approvals to Your Laravel Application

Read article
Enhancing Data Processing with Laravel's transform() Method image

Enhancing Data Processing with Laravel's transform() Method

Read article
Get Xdebug Working With Docker and PHP 8.4 in One Minute image

Get Xdebug Working With Docker and PHP 8.4 in One Minute

Read article