Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
89 changes: 89 additions & 0 deletions src/lib/apply-website-info-head.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,89 @@
/**
* IMAGINE-MANAGED FILE.
* Do not edit this file manually or with AI.
* Changes may be overwritten by Imagine.
*/

import { websiteInfo } from './website-info'

type HeadMetaEntry = Record<string, unknown>
type HeadLinkEntry = Record<string, unknown>

function withoutWebsiteInfoMeta(meta: HeadMetaEntry[]) {
return meta.filter((entry) => {
if (typeof entry.title === 'string') {
return false
}

const key =
typeof entry.name === 'string'
? entry.name
: typeof entry.property === 'string'
? entry.property
: ''
return ![
'description',
'og:title',
'og:description',
'og:image',
'og:type',
'twitter:card',
'twitter:title',
'twitter:description',
'twitter:image',
].includes(key)
})
}

function withoutWebsiteInfoLinks(links: HeadLinkEntry[]) {
return links.filter((entry) => {
const rel = typeof entry.rel === 'string' ? entry.rel : ''
return rel !== 'icon' && rel !== 'shortcut icon'
})
}

export function applyWebsiteInfoHead<
T extends {
meta?: HeadMetaEntry[]
links?: HeadLinkEntry[]
[key: string]: unknown
},
>(input: T) {
const meta = withoutWebsiteInfoMeta(input.meta ?? [])
const links = withoutWebsiteInfoLinks(input.links ?? [])
const title = websiteInfo.title ?? 'Imagine App'

return {
...input,
meta: [
...meta,
{ title },
{ property: 'og:title', content: title },
{ property: 'og:type', content: 'website' },
{
name: 'twitter:card',
content: websiteInfo.ogImageUrl ? 'summary_large_image' : 'summary',
},
{ name: 'twitter:title', content: title },
...(websiteInfo.description
? [
{ name: 'description', content: websiteInfo.description },
{ property: 'og:description', content: websiteInfo.description },
{ name: 'twitter:description', content: websiteInfo.description },
]
: []),
...(websiteInfo.ogImageUrl
? [
{ property: 'og:image', content: websiteInfo.ogImageUrl },
{ name: 'twitter:image', content: websiteInfo.ogImageUrl },
]
: []),
],
links: [
...links,
...(websiteInfo.faviconUrl
? [{ rel: 'icon', href: websiteInfo.faviconUrl }]
: []),
],
} satisfies T
}
20 changes: 20 additions & 0 deletions src/lib/website-info.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
/**
* IMAGINE-MANAGED FILE.
* Do not edit this file manually or with AI.
* Update Website Info from the Imagine Studio settings.
* Changes may be overwritten by Imagine.
*/

export type WebsiteInfo = {
title: string | null
description: string | null
faviconUrl: string | null
ogImageUrl: string | null
}

export const websiteInfo: WebsiteInfo = {
title: 'Imagine App',
description: null,
faviconUrl: null,
ogImageUrl: null,
}
6 changes: 4 additions & 2 deletions src/routes/__root.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ import {
OGImageConfig,
OGMetaTags,
} from '@/lib/og-config'
import { applyWebsiteInfoHead } from '@/lib/apply-website-info-head'

interface MyRouterContext {
queryClient: QueryClient
Expand Down Expand Up @@ -43,6 +44,7 @@ export const Route = createRootRouteWithContext<MyRouterContext>()({
baseUrl,
}
},

head: ({ loaderData }) => {
const baseUrl =
typeof window !== 'undefined'
Expand All @@ -64,7 +66,7 @@ export const Route = createRootRouteWithContext<MyRouterContext>()({

const ogTags = createOGMetaTags(metadata)

return {
return applyWebsiteInfoHead({
meta: [
{
charSet: 'utf-8',
Expand All @@ -85,7 +87,7 @@ export const Route = createRootRouteWithContext<MyRouterContext>()({
},
],
scripts: [...scripts],
}
})
},

shellComponent: RootDocument,
Expand Down
Loading