0👍
I believe you need a server to fix this problem for you so pages should be SSR or you need to generate these pages in build time (SSG).
you can use useHead
composable too, but I think you should use SSR or SSG at least for these pages:
The properties of
useHead
can be dynamic, accepting ref, computed, and reactive properties. meta parameter can also accept a function returning an object to make the entire object reactive.
learn more here: https://nuxt.com/docs/api/composables/use-head
pls check this:https://stackblitz.com/edit/nuxt-starter-51pnfj
and there is a mistake in your code. your code should be this if you using composition API :
<Head>
<Meta hid="og:url" property="og:url" :content="`https://my-site.com${route.path}`" />
</Head>
<script setup>
const route = useRoute();
</script>
if you using option API your code should be this:
<Head>
<Meta hid="og:url" property="og:url" :content="`https://my-site.com${$route.path}`" />
</Head>
if you didn’t set ssr
to false
, by default it will be true or if you don’t want SSR for all pages I think you can use Hybrid rendering. so the result will be this :
0👍
Have you tried define-nuxt-route-middleware? it allows to run your Composables Function at the build time. So your meta should’ve applied properly for SEO. Instead, i use definePageMeta rather than useHead in every page like so :
[some page].vue
<script setup>
definePageMeta({
order: 1,
label: "Perusahaan",
title: "Perusahaan/Klien",
description:
"Kami memudahkan administrasi, semua absensi pekerja dapat dengan mudah dilacak riwayatnya serta memantau serta mengatur kehadiran pekerja dengan Geotagging dan pengelompokan area kerja untuk perusahaan atau klien",
icon: "domain",
transparent: true,
image: "/perusahaan/invoice.png",
});
<script/>
And use useHead once,
middleware/meta.js
export default defineNuxtRouteMiddleware(async (to, from) => {
let data = null,
url = null,
params = null;
if (to.fullPath?.includes("berita") && to?.params?.slug) {
url = new URL(`${useRuntimeConfig().public?.database}/Articles/get`);
params = {
jsonQuery: JSON.stringify({
slug: to?.params?.slug,
}),
limit: 1,
};
} else if (to.fullPath?.includes("faq") && to?.params?.id) {
url = new URL(`${useRuntimeConfig().public?.database}/FAQ/get`);
params = {
jsonQuery: JSON.stringify({
_id: to?.params?.id,
}),
limit: 1,
};
// console.log(data);
}
if (url && params) {
Object.keys(params).forEach((key) =>
url.searchParams.append(key, params[key])
);
data = await fetch(url, {
method: "GET",
});
data = await data?.json();
}
if (data?.success)
data = data?.result?.[0];
if (data || (to?.meta?.title && to?.meta?.description)) {
useHead(
useNuxtApp().$metaGenerator(
data?.title || to?.meta?.title,
data?.description || data?.excerpt || to?.meta?.description,
to?.fullPath,
data?.picture || to?.meta?.image,
to?.meta?.keywords
)
);
}
});
$metaGenerator (plugins/index.js) :
export default defineNuxtPlugin((nuxtApp) => {
return {
metaGenerator: (
title,
description,
path,
image,
keywords,
site = "@website"
) => {
const defaultKeywords = [
"lowongan kerja",
];
if (Array.isArray(keywords)) keywords.concat(defaultKeywords);
else keywords = defaultKeywords.concat(keywords || "");
if (!image) {
image = "/favicon.ico";
}
const url =
`${useRuntimeConfig().hostname}${path}` ||
useRuntimeConfig().hostname;
return {
title,
meta: [
{
name: "description",
content: description,
},
{
rel: "canonical",
href: url,
},
{
rel: "amphtml",
href: url,
},
{
name: "keywords",
content: keywords,
},
// google
{
itemprop: "name",
content: title,
},
{
itemprop: "description",
content: description,
},
{
itemprop: "image",
content: image,
},
// twitter card
{
name: "twitter:card",
content: "summary_large_image",
},
{ name: "twitter:site", content: site },
{
name: "twitter:title",
content: title,
},
{
name: "twitter:description",
content: description,
},
{
name: "twitter:image",
content: image,
},
{
name: "twitter:image:alt",
content: title,
},
{
name: "twitter:url",
content: url,
},
// Open Graph
{ property: "og:site_name", content: site },
{ property: "og:type", content: "website" },
{
property: "og:title",
content: title,
},
{
property: "og:description",
content: description,
},
{
property: "og:image",
content: image,
},
{
property: "og:url",
content: url,
},
{
property: "og:image:secure_url",
content: image,
},
{
property: "og:image:alt",
content: title,
},
],
link: [
{
rel: "canonical",
href: url,
},
{
rel: "amphtml",
href: url,
},
],
};
},
}
})
0👍
useSeoMeta
works for me while useHead
does not. I was trying to change the description meta using the following code.
useSeoMeta({
description: () => 'New meta description',
});
- [Vuejs]-[Vue warn]: Extraneous non-props attributes (id) were passed to component but could not be automatically inherited because component renders fragment
- [Vuejs]-Unable to make api call from vue.js project hosted on firebase to node.js backend stored in third party server