1 ---
2 // Import the global.css file here so that it is included on
3 // all pages through the use of the <BaseHead /> component.
4 import { SITE } from '@/config'
5 import type { BaseHeadProps } from '@/types/component.types'
6 import { getLangFromUrl, getAlternateUrl } from '@/i18n/utils'
7 import 'katex/dist/katex.min.css'
8
9 const canonicalURL = new URL(Astro.url.pathname, Astro.site)
10 const currentLang = getLangFromUrl(Astro.url)
11 const alternateLang = currentLang === 'id' ? 'en' : 'id'
12 const alternateUrl = new URL(getAlternateUrl(Astro.url, alternateLang), Astro.site)
13
14 const { title, description } = Astro.props as BaseHeadProps
15 ---
16
17 <!-- Global Metadata -->
18 <meta charset="utf-8" />
19 <meta name="viewport" content="width=device-width,initial-scale=1" />
20 {SITE.fadeAnimation && <meta name="view-transition" content="same-origin" />}
21 <link rel="icon" type="image/svg+xml" href="/favicon.svg" />
22 <link rel="apple-touch-icon" href="/apple-touch-icon.png" />
23 <link rel="preload" href="/fonts/Inter.woff2" as="font" type="font/woff2" crossorigin="anonymous" />
24 <link
25 rel="preload"
26 href="/fonts/Besley-Italic.woff2"
27 as="font"
28 type="font/woff2"
29 crossorigin="anonymous"
30 />
31 <link rel="sitemap" href="/sitemap-index.xml" />
32 <link
33 rel="alternate"
34 type="application/rss+xml"
35 title={SITE.title}
36 href={new URL('rss.xml', Astro.site)}
37 />
38 <meta name="generator" content={Astro.generator} />
39
40 <!-- Canonical URL -->
41 <link rel="canonical" href={canonicalURL} />
42
43 <!-- Alternate Languages -->
44 <link rel="alternate" hreflang={currentLang} href={canonicalURL} />
45 <link rel="alternate" hreflang={alternateLang} href={alternateUrl} />
46 <link rel="alternate" hreflang="x-default" href={new URL('/', Astro.site)} />
47
48 <!-- Primary Meta Tags -->
49 <title>
50 {title || SITE.title}
51 </title>
52 <meta name="title" content={title} />
53 <meta name="description" content={description} />
54
55 <!-- Open Graph / Facebook -->
56 <meta property="og:type" content="website" />
57 <meta property="og:url" content={Astro.url} />
58 <meta property="og:title" content={title} />
59 <meta property="og:description" content={description} />
60 <meta property="og:image" content={new URL('/chiri-og.png', Astro.url)} />
61 <meta property="og:locale" content={currentLang === 'id' ? 'id_ID' : 'en_US'} />
62 <meta property="og:locale:alternate" content={currentLang === 'id' ? 'en_US' : 'id_ID'} />
63
64 <!-- Twitter -->
65 <meta property="twitter:card" content="summary_large_image" />
66 <meta property="twitter:url" content={Astro.url} />
67 <meta property="twitter:title" content={title} />
68 <meta property="twitter:description" content={description} />
69 <meta property="twitter:image" content={new URL('/chiri-og.png', Astro.url)} />
70
71 <!-- Transitions Initialization -->
72 <script is:inline define:vars={{ fadeAnimation: SITE.fadeAnimation }}>
73 function initMotionPref(doc = document) {
74 const prefersReducedMotion = window.matchMedia('(prefers-reduced-motion: reduce)').matches
75 const supportsViewTransitions = 'startViewTransition' in document
76
77 doc.documentElement.classList.toggle('reduce-motion', prefersReducedMotion)
78
79 doc.documentElement.classList.toggle(
80 'disable-transitions',
81 !fadeAnimation || !supportsViewTransitions
82 )
83
84 doc.documentElement.classList.add('js')
85 }
86
87 initMotionPref()
88
89 document.addEventListener('astro:before-swap', ({ newDocument }) => {
90 initMotionPref(newDocument)
91 })
92
93 document.addEventListener('astro:page-load', () => {
94 initMotionPref()
95 })
96
97 document.addEventListener('visibilitychange', () => {
98 if (document.visibilityState === 'visible') {
99 initMotionPref()
100 }
101 })
102
103 window.addEventListener('pageshow', () => {
104 initMotionPref()
105 })
106 </script>