JAVASCRIPT
Vue 3 Head Management with `useHead` (VueUse)
Learn to dynamically manage document head tags (title, meta, etc.) in your Vue 3 application using the `useHead` composable from VueUse, essential for SEO and social sharing.
// main.js
/*
import { createApp } from 'vue';
import App from './App.vue';
import { createHead } from '@vueuse/head';
const app = createApp(App);
const head = createHead();
app.use(head);
app.mount('#app');
*/
// src/views/ProductDetail.vue
<template>
<div class="product-detail">
<h1>{{ product.name }}</h1>
<p>{{ product.description }}</p>
<img :src="product.imageUrl" :alt="product.name" />
<p>Price: ${{ product.price }}</p>
<router-link to="/">Back to Home</router-link>
</div>
</template>
<script setup>
import { ref, watchEffect } from 'vue';
import { useRoute } from 'vue-router';
import { useHead } from '@vueuse/head'; // Make sure @vueuse/head is installed and configured
const route = useRoute();
const productId = route.params.id;
const product = ref({});
// Simulate fetching product data
const fetchProduct = async (id) => {
// In a real application, you would fetch from an API
await new Promise(resolve => setTimeout(resolve, 500)); // Simulate API call
const mockProducts = {
'1': {
id: 1,
name: 'Super Widget',
description: 'The ultimate widget for all your needs.',
imageUrl: 'https://via.placeholder.com/400x300/FF5733/FFFFFF?text=Super+Widget',
price: 99.99
},
'2': {
id: 2,
name: 'Mega Gadget',
description: 'A powerful gadget that revolutionizes efficiency.',
imageUrl: 'https://via.placeholder.com/400x300/3366FF/FFFFFF?text=Mega+Gadget',
price: 199.99
}
};
product.value = mockProducts[id] || {};
};
watchEffect(async () => {
if (productId) {
await fetchProduct(productId);
}
});
// Dynamically update head properties based on product data
useHead(() => ({
title: product.value.name ? `${product.value.name} | My Store` : 'Product Detail | My Store',
meta: [
{ name: 'description', content: product.value.description || 'View details of our products.' },
{ property: 'og:title', content: product.value.name || 'Product Detail' },
{ property: 'og:description', content: product.value.description || 'View details of our products.' },
{ property: 'og:image', content: product.value.imageUrl || 'https://via.placeholder.com/1200x630/CCCCCC/000000?text=My+Store' },
{ name: 'twitter:card', content: 'summary_large_image' },
]
}));
</script>
<style scoped>
.product-detail {
max-width: 800px;
margin: 20px auto;
padding: 20px;
border: 1px solid #eee;
border-radius: 8px;
text-align: center;
}
img {
max-width: 100%;
height: auto;
border-radius: 4px;
margin-bottom: 15px;
}
h1 {
color: #333;
margin-bottom: 10px;
}
p {
color: #555;
line-height: 1.6;
}
a {
display: inline-block;
margin-top: 20px;
padding: 10px 15px;
background-color: #42b983;
color: white;
text-decoration: none;
border-radius: 5px;
}
</style>
// You would also need vue-router configured in your app
// router/index.js
/*
import { createRouter, createWebHistory } from 'vue-router';
import HomeView from '../views/HomeView.vue';
import ProductDetail from '../views/ProductDetail.vue';
const routes = [
{ path: '/', name: 'Home', component: HomeView },
{ path: '/product/:id', name: 'ProductDetail', component: ProductDetail }
];
const router = createRouter({
history: createWebHistory(),
routes,
});
export default router;
*/
How it works: This snippet demonstrates dynamic management of the HTML `<head>` section in a Vue 3 application using the `useHead` composable from `@vueuse/head`. It's crucial for SEO and social media sharing, allowing you to set page titles, meta descriptions, Open Graph tags, and more, based on component data. The `ProductDetail.vue` example fetches product data and then uses `useHead` to update the document's title and various meta tags, ensuring that search engines and social platforms display relevant and up-to-date information for each product page.