harlan-zw/nuxt-schema-org

Is it possible to omit or override "about" property of WebPage?

iaverdieck opened this issue · 4 comments

Details

The "about" field always defaults to the identity like in this case.

 {
      "@id": "http://localhost:3000/some/path/other/than/homepage/#webpage",
      "@type": "WebPage",
      "description": "Some Page that is not about the Organisation",
      "name": "Current page | My Website",
      "url": "http://localhost:3000/some/path/other/than/homepage",
      "about": {
        "@id": "http://localhost:3000/#identity"
      },
...

I would like to omit the "about" property or override it with i.e. {'@type': 'Thing', ...} is that possible?

On every route I set:

useHead({
	templateParams: {
		schemaOrg: {
			host: `${NUXT_SERVER_URL}/`,
			trailingSlash: 'true',
		},
	},
});

useSchemaOrg([
	defineOrganization({
		logo: `${NUXT_SERVER_URL}/images/global/Logo.png`,
		url: `${NUXT_SERVER_URL}/`,
		name: 'My Org',
	}),
	defineWebSite({
		url: `${NUXT_SERVER_URL}/`,
		name: 'My Website',
		publisher: {
			'@type': 'Organization',
			'@id': `${NUXT_SERVER_URL}/#organization`,
		},
		potentialAction: [],
	}),
]);

and for the actual route of the page I set:

useSchemaOrg([
	defineWebPage({
		name: props.story.title,
		primaryImageOfPage: defineImage({
			url:
				props.story.header_image.webpUrl ??
				props.story.header_image.fallbackUrl,
		}),
		potentialAction: [],
	}),
]);

when I try to override it with thing:

useSchemaOrg([
	defineWebPage({
		name: props.story.title,
		primaryImageOfPage: defineImage({
			url:
				props.story.header_image.webpUrl ??
				props.story.header_image.fallbackUrl,
		}),
		potentialAction: [],
		about: {
			'@type': 'Thing',
			name: 'Some thing',
		}
	}),
]);

Then I get for the about property:

"about": {
        "@type": [
          "Organization",
          "Thing"
        ],
        "name": "Some thing",
        "url": "http://localhost:3000/"
      },

Could you help me with that?

Best regards,
Ilja

@harlan-zw Running into similar issues....

I have set up an identity in nuxt.config.ts

schemaOrg: {
    identity: {
      type: 'Organization',
      name: '<org name>',
      url: '<org url>,
      logo: "<logo url>",
      sameAs: [
        "<social urls>",
      ],
      // more props from Organization schema
  }
}

This results in every webpage having an Organization schema, and WebPage.about, conform unhead docs

But I also have webpages that are profiles of other organizations or people... And I want to override the global identity for these pages. For example

// ./pages/organizations/[slug].vue

const img = useImage()
useSchemaOrg([
  defineOrganization({
    name: page.value?.name || page.value?.title,
    logo: img(page.value?.logo.public_id, { width: 400, fit: "fit" }),
    url: page.value?.website,
    image: metaImage(page.value?.image),
    address: !!page.value?.city
      ? {
          streetAddress: page.value?.street + page.value?.streetNmbr,
          addressLocality: page.value?.city,
          postalCode: page.value?.zip,
          addressCountry: "NL",
        }
      : undefined,
    sameAs: page.value?.links,
  }),
]);

I would expect that defineOrganization() would override the relevant identity props, but it's more of a merge... The example above results in

  • Organization.sameAs links that contain both links from global identity, as well as links provided in defineOrganization()
  • WebPage.about has all props from global config, overridden by any values that are provided within defineOrganization(). So this is a mixture between the two
  • WebPage. isPartOf.publisher is equal to WebPage.about, so a mixture between global identity and the route data.

Is this a bug? A feature? Or am I using the API in the wrong way? The only possible workaround I can see, is to disable the global identity and set everything on a per route basis....

Hi, sorry for the delay in response.

You've correctly identified the issue, it is doing a merge. For ease of use, just calling defineOrganization will by default merge the global #identity, which is the "owner" of the site.

If you'd like to just add a new organization, all you need to do is add an explicit @id. The docs are clearly in need of some work here, I've added an issue here to at least document this unjs/unhead#390

The relevant logic is here if it's useful: https://github.com/unjs/unhead/blob/main/packages/schema-org/src/core/util.ts#L38

I don't think it's possible to remove a node already registered without some hacks, so disabling defaults and re-implementing in relevant layouts may make more sense for your use case.

Thanks for the reply! I indeed disabled the defaults in nuxt.config and wrote a composable to handle the logic.

I've added a guide for deduping nodes https://unhead.unjs.io/schema-org/guides/deduping-nodes.

In the latest version it's possible to dedupe a node by providing a tagDuplicateStrategy as an option to the schema.org.

useSchemaOrg([
  defineOrganization({
    '@id': '#some-company',
    "name": 'Foo Company',
  })
], {
  tagDuplicateStrategy: 'replace'
})

This follows the same convention as useHead, however, it's the opposite. In the v2 we may consider swapping the duplicate strategy to replace by default.