diff --git a/packages/nuxt-ripple/composables/use-merge-section-tags.ts b/packages/nuxt-ripple/composables/use-merge-section-tags.ts new file mode 100644 index 0000000000..e0bba9eb97 --- /dev/null +++ b/packages/nuxt-ripple/composables/use-merge-section-tags.ts @@ -0,0 +1,33 @@ +import { setResponseHeader, getResponseHeaders } from 'h3' + +// Merge two section cache tags string and deduplicate tag +// Return a string of merged tags +const mergeTags = (existingTags: string, newTags: string): string => { + const tags1 = existingTags.split(' ') + const tags2 = newTags.split(' ') + const tags = [...new Set([...tags1, ...tags2])] + return tags.join(' ') +} + +export const useMergeSectionTags = async ( + sectionCacheTags: any +): Promise => { + const event = useRequestEvent() + // Section.io cache tags must be set on the response header to invalidate the cache after a change in drupal + if (sectionCacheTags) { + const currentResponseHeaders = getResponseHeaders(event) + + const currentSectionTags: string = + currentResponseHeaders && currentResponseHeaders['section-cache-tags'] + ? (currentResponseHeaders['section-cache-tags'] as string) + : ('' as string) + + setResponseHeader( + event, + 'section-cache-tags', + mergeTags(currentSectionTags, sectionCacheTags) + ) + } +} + +export default useMergeSectionTags diff --git a/packages/nuxt-ripple/composables/use-tide-page.ts b/packages/nuxt-ripple/composables/use-tide-page.ts index 25a679149d..6e08354e1f 100644 --- a/packages/nuxt-ripple/composables/use-tide-page.ts +++ b/packages/nuxt-ripple/composables/use-tide-page.ts @@ -1,5 +1,4 @@ import type { TidePageBase } from './../types' -import { appendResponseHeader } from 'h3' import { useCookie, isPreviewPath, AuthCookieNames } from '#imports' const isCacheTimeExpired = (date: number, expiryInMinutes = 5) => { @@ -15,7 +14,6 @@ export const useTidePage = async ( ): Promise => { const route = useRoute() const path = slug || route.path - const event = useRequestEvent() const { public: config } = useRuntimeConfig() const siteId = site || config.tide?.site @@ -73,7 +71,7 @@ export const useTidePage = async ( // Section.io cache tags must be set on the response header to invalidate the cache after a change in drupal if (sectionCacheTags) { - appendResponseHeader(event, 'section-cache-tags', sectionCacheTags) + useMergeSectionTags(sectionCacheTags) } if (error && error.value?.statusCode) { diff --git a/packages/nuxt-ripple/composables/use-tide-site.ts b/packages/nuxt-ripple/composables/use-tide-site.ts index a2ee9fb0cb..af93e8becb 100644 --- a/packages/nuxt-ripple/composables/use-tide-site.ts +++ b/packages/nuxt-ripple/composables/use-tide-site.ts @@ -4,12 +4,18 @@ export const useTideSite = async (id?: number): Promise => { const { public: config } = useRuntimeConfig() const siteId = id || config.tide?.site const { data: siteData } = useNuxtData(`site-${siteId}`) + + let sectionCacheTags + if (!siteData.value) { const { data, error } = await useFetch('/api/tide/site', { key: `site-${siteId}`, baseURL: config.apiUrl || '', params: { id: siteId + }, + async onResponse({ response }) { + sectionCacheTags = response.headers.get('section-cache-tags') } }) if (error && error.value?.statusCode) { @@ -17,6 +23,12 @@ export const useTideSite = async (id?: number): Promise => { console.log('API error fetching site data') useTideError(500) } + + // Section.io cache tags must be set on the response header to invalidate the cache after a change in drupal + if (sectionCacheTags) { + useMergeSectionTags(sectionCacheTags) + } + return data.value } return siteData.value diff --git a/packages/nuxt-ripple/server/api/tide/site.ts b/packages/nuxt-ripple/server/api/tide/site.ts index b8cb9d6857..4140319f99 100644 --- a/packages/nuxt-ripple/server/api/tide/site.ts +++ b/packages/nuxt-ripple/server/api/tide/site.ts @@ -15,7 +15,16 @@ export const createSiteHandler = async ( throw new BadRequestError('Site id is required') } - return await tideSiteApi.getSiteData(query.id) + const siteResponse = await tideSiteApi.getSiteData(query.id) + + // Need to pass on the section cache tags to the nuxt app + setResponseHeader( + event, + 'section-cache-tags', + siteResponse.headers['section-cache-tags'] + ) + + return siteResponse.data }) } diff --git a/packages/ripple-tide-api/src/services/tide-site.ts b/packages/ripple-tide-api/src/services/tide-site.ts index 840bea507a..27b324cd0e 100644 --- a/packages/ripple-tide-api/src/services/tide-site.ts +++ b/packages/ripple-tide-api/src/services/tide-site.ts @@ -38,16 +38,22 @@ export default class TideSite extends TideApiBase { } } try { - const { data: response } = await this.get(`/taxonomy_term/sites`, { - params - }) + const { data: response, headers } = await this.get( + `/taxonomy_term/sites`, + { + params + } + ) if (response && response.data.length > 0) { const resource = jsonapiParse.parse(response).data[0] const siteData = await this.getMappedData( this.siteMapping.mapping, resource ) - return siteData + return { + data: siteData, + headers + } } } catch (error: any) { throw new ApplicationError('Error fetching site data', { cause: error })