554cb99f2c
Add the Umami tracker (cookieless, no consent banner) in the document head, limited to the production hostnames via data-domains so dev traffic doesn't pollute the stats. Pageviews are auto-tracked per page and locale. Custom events on the key funnel: - demo-request (demo form submit, with teamSize) - partner-application (partner form submit, with type) - book-demo (every "Book a demo" CTA click) via data-umami-event - login (clicks through to the app) Also fix the mobile nav menu links, which weren't localized (would drop Danish visitors back to English).
66 lines
2.6 KiB
TypeScript
66 lines
2.6 KiB
TypeScript
import { computed } from 'vue'
|
|
import { COPY, type Lang } from '~/utils/landingCopy'
|
|
import { makeTheme } from '~/utils/landingTokens'
|
|
|
|
// Locale is owned by @nuxtjs/i18n (URL-based: English at /, Danish at /da, with
|
|
// cookie-remembered browser detection). useLang exposes it as the 'da' | 'en'
|
|
// the COPY object expects; useCopy maps to the matching translations. `dark` is
|
|
// unused machinery from the design's Tweaks panel (the site is light-only).
|
|
export const useLang = () => {
|
|
const { locale } = useI18n()
|
|
return computed<Lang>(() => (locale.value === 'da' ? 'da' : 'en'))
|
|
}
|
|
export const useDark = () => useState<boolean>('dz-dark', () => false)
|
|
|
|
export const useTheme = () => {
|
|
const dark = useDark()
|
|
return computed(() => makeTheme(dark.value))
|
|
}
|
|
|
|
export const useCopy = () => {
|
|
const { locale } = useI18n()
|
|
return computed(() => COPY[locale.value === 'da' ? 'da' : 'en'])
|
|
}
|
|
|
|
// Setup-only. Returns a click handler that switches to the other locale's
|
|
// localized route (flips the URL, e.g. / <-> /da).
|
|
export function useLangToggle() {
|
|
const { locale } = useI18n()
|
|
const switchLocalePath = useSwitchLocalePath()
|
|
return () => navigateTo(switchLocalePath(locale.value === 'da' ? 'en' : 'da'))
|
|
}
|
|
|
|
// Setup-only. Localizes an internal href, preserving any #hash. Page links get
|
|
// the locale prefix (/about -> /da/about in Danish); section anchors resolve
|
|
// against the current locale's home (/#suite -> /da#suite). Bare #hash returns
|
|
// unchanged (same-page anchor).
|
|
export function useLocalizeHref() {
|
|
const localePath = useLocalePath()
|
|
return (href: string) => {
|
|
if (href.startsWith('#')) return href
|
|
const i = href.indexOf('#')
|
|
const path = i === -1 ? href : href.slice(0, i)
|
|
const hash = i === -1 ? '' : href.slice(i)
|
|
return localePath(path || '/') + hash
|
|
}
|
|
}
|
|
|
|
// Fire a custom Umami event. No-op on the server and when the tracker isn't
|
|
// active (e.g. localhost dev, where data-domains limits it to dezky.eu).
|
|
export function track(event: string, data?: Record<string, unknown>) {
|
|
if (!import.meta.client) return
|
|
const u = (window as unknown as { umami?: { track: (e: string, d?: unknown) => void } }).umami
|
|
u?.track(event, data)
|
|
}
|
|
|
|
// Smooth-scroll to an in-page anchor, accounting for the sticky 72px nav.
|
|
// Non-anchor / placeholder links (#) are ignored.
|
|
export function scrollToAnchor(hash: string) {
|
|
if (!hash || hash === '#' || !hash.startsWith('#')) return
|
|
const el = document.getElementById(hash.slice(1))
|
|
if (!el) return
|
|
const top = el.getBoundingClientRect().top + window.scrollY - 72
|
|
window.scrollTo({ top, behavior: 'smooth' })
|
|
history.replaceState(null, '', hash)
|
|
}
|