Skip to content

Commit

Permalink
fix(@dpc-sdp/nuxt-ripple): fixed unpredictable meta tags by moving fr…
Browse files Browse the repository at this point in the history
…om hooks to composibles
  • Loading branch information
jeffdowdle committed Jan 31, 2024
1 parent f441204 commit 2ea34b4
Show file tree
Hide file tree
Showing 8 changed files with 198 additions and 211 deletions.
7 changes: 6 additions & 1 deletion packages/nuxt-ripple/components/TideBaseLayout.vue
Original file line number Diff line number Diff line change
Expand Up @@ -142,6 +142,7 @@ onMounted(() => {
document.body.setAttribute('data-nuxt-hydrated', 'true')
})
const nuxtApp = useNuxtApp()
const route = useRoute()
const showBreadcrumbs = computed(() => route.path !== '/')
const showDraftAlert = computed(() => props.page?.status === 'draft')
Expand All @@ -163,9 +164,13 @@ const footerNav = computed(() => {
return menuMain
})
const nuxtApp = useNuxtApp()
/*
* This hook can be called from plugins to extend Tide managed pages behaviour - see /plugins folder for examples
*/
nuxtApp.callHook('tide:page', props)
useTideSiteTheme(props.site)
useTideHideAlerts()
useTideSiteMeta(props, nuxtApp?.$app_origin)
useTideFavicons()
</script>
29 changes: 29 additions & 0 deletions packages/nuxt-ripple/composables/use-tide-favicons.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
export default () => {
useHead({
link: [
{
rel: 'apple-touch-icon',
sizes: '180x180',
href: '/apple-touch-icon.png'
},
{
rel: 'icon',
type: 'image/png',
sizes: '32x32',
href: '/favicon-32x32.png'
},
{
rel: 'icon',
type: 'image/png',
sizes: '16x16',
href: '/favicon-16x16.png'
},
{ rel: 'manifest', href: '/site.webmanifest' },
{ rel: 'mask-icon', href: '/safari-pinned-tab.svg', color: '#0054c9' }
],
meta: [
{ name: 'msapplication-TileColor', content: '#0054c9' },
{ name: 'theme-color', content: '#ffffff' }
]
})
}
Original file line number Diff line number Diff line change
@@ -1,5 +1,3 @@
import { useHead } from '#imports'

/**
* This script needs to be loaded as the very first asset on the page in order to avoid
* the alerts showing that the user has already dismissed
Expand Down Expand Up @@ -46,14 +44,12 @@ try {
console.error(e)
}`

export default defineNuxtPlugin((nuxtApp) => {
nuxtApp.hook('tide:page', () => {
useHead({
script: [
{
innerHTML: hideAlertsOnLoadScript
}
]
})
export default () => {
useHead({
script: [
{
innerHTML: hideAlertsOnLoadScript
}
]
})
})
}
130 changes: 130 additions & 0 deletions packages/nuxt-ripple/composables/use-tide-site-meta.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,130 @@
const metaProperty = (str: string) => {
const p = str.split(':')
if (p.length === 1) return str
return p[0] + p[1].charAt(0).toUpperCase() + p[1].slice(1)
}

export default (props, $app_origin) => {
const page = props.page
const site = props.site

const pageTitle = computed(() => {
const titleOfPage = `${props.pageTitle || props.page?.title || ''}`
const titleOfSite = `${props.site?.name}`
if (titleOfPage && titleOfSite) {
return `${titleOfPage} | ${titleOfSite}`
}
return titleOfSite
})

if (!page) {
useHead({
title: pageTitle
})
} else {
// Additional <link>s in head
const links = []
const additionalMeta = page?.meta?.additional || []

additionalMeta
.filter(
(attr: any) =>
attr.tag === 'link' && attr.attributes.rel !== 'canonical'
)
.map((attr: any) => {
if (attr.attributes.rel) links.push(attr.attributes)
})

// Define basic attributes
useHead({
link: links
})

// Override API values with metatag
const metaDescriptions = {
ogDescription: '',
description: ''
},
metaOverrides = {}
additionalMeta
.filter(
(attr: any) => attr.tag === 'meta' && attr.attributes.name !== 'title'
)
.map((attr: any) => {
if (attr.attributes.name || attr.attributes.property)
if (
['ogDescription', 'description'].includes(
metaProperty(attr.attributes.name || attr.attributes.property)
)
) {
// Keep description fields in a separate collection
metaDescriptions[
metaProperty(attr.attributes.name || attr.attributes.property)
] = attr.attributes.content
} else {
metaOverrides[
metaProperty(attr.attributes.name || attr.attributes.property)
] = attr.attributes.content
}
})

// Determine unified description
let description = page.meta?.description

if (metaDescriptions.ogDescription !== '') {
description = metaDescriptions.ogDescription
} else if (metaDescriptions.description !== '') {
description = metaDescriptions.description
}

// Determine images
let featuredImage = '',
featuredImageAlt = ''
if (page.meta?.image) {
featuredImage = page.meta.image.src
featuredImageAlt = page.meta.image.alt
} else if (site.socialImages.og) {
featuredImage = site.socialImages.og.src
featuredImageAlt = site.socialImages.og.alt
}

let twitterImage = '',
twitterImageAlt = ''
if (page.meta?.image) {
twitterImage = page.meta.image.src
twitterImageAlt = page.meta.image.alt
} else if (site.socialImages.twitter) {
twitterImage = site.socialImages.twitter.src
twitterImageAlt = site.socialImages.twitter.alt
} else if (site.socialImages.og) {
twitterImage = site.socialImages.og.src
twitterImageAlt = site.socialImages.og.alt
}

// Define SEO meta
useSeoMeta({
title: () => pageTitle.value,
description: () => description,
ogTitle: props.pageTitle,
ogDescription: description,
ogType: 'website',
ogUrl: $app_origin + page.meta?.url,
ogImage: featuredImage,
ogImageAlt: featuredImageAlt,
twitterCard: 'summary',
twitterSite: $app_origin,
twitterTitle: props.pageTitle,
twitterDescription: description,
twitterImage: twitterImage,
twitterImageAlt: twitterImageAlt,
keywords: page.meta?.keywords,

// Custom props
sitesection: props.siteSection ? props.siteSection.name : null,
'content-type': page.type && page.type.replace('node--', ''),

// Metatag escape hatch
...metaOverrides
})
}
}
25 changes: 25 additions & 0 deletions packages/nuxt-ripple/composables/use-tide-site-theme.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
import { defu as defuMerge } from 'defu'

const formatThemeStyle = (themeObj) => {
if (themeObj) {
return Object.keys(themeObj)
.map((key) => {
return `--${key}: ${themeObj[key]}`
})
.join(`;\r\n`)
}
}

export default (site) => {
const siteTheme = defuMerge(site?.theme, useAppConfig()?.ripple?.theme || {})
const style = formatThemeStyle(siteTheme)
if (style) {
useHead({
style: [
{
children: `:root, body { ${style} }`
}
]
})
}
}
31 changes: 0 additions & 31 deletions packages/nuxt-ripple/plugins/favicons.ts

This file was deleted.

31 changes: 0 additions & 31 deletions packages/nuxt-ripple/plugins/site-theme.ts

This file was deleted.

Loading

0 comments on commit 2ea34b4

Please sign in to comment.