Fork of Chiri for Astro for my blog
0
fork

Configure Feed

Select the types of activity you want to include in your feed.

fix(favicon): optimize cache strategy

the3ash c9b14e65 aefddc95

+55 -53
+8 -3
netlify.toml
··· 32 32 default-src 'self'; 33 33 script-src 'self' 'unsafe-inline' 'unsafe-eval' https:; 34 34 style-src 'self' 'unsafe-inline' https:; 35 - img-src 'self' data: https: blob:; 35 + img-src 'self' data: https: blob: 'unsafe-inline'; 36 36 font-src 'self' data: https:; 37 37 frame-src https:; 38 - connect-src 'self' https:; 38 + connect-src 'self' https: blob:; 39 39 object-src 'none'; 40 40 worker-src 'self' blob:; 41 41 child-src 'self' blob:; ··· 103 103 [[headers]] 104 104 for = "/favicon.svg" 105 105 [headers.values] 106 - Cache-Control = "no-cache, no-store, must-revalidate" 106 + Cache-Control = "no-cache, no-store, must-revalidate, max-age=0, s-maxage=0" 107 107 Pragma = "no-cache" 108 108 Expires = "0" 109 109 Vary = "Accept-Encoding" 110 + Surrogate-Control = "no-store" 111 + Surrogate-Key = "favicon" 112 + Access-Control-Allow-Origin = "*" 113 + Access-Control-Allow-Methods = "GET, OPTIONS" 114 + Access-Control-Allow-Headers = "Cache-Control, Pragma" 110 115 111 116 # Homepage with resource hints 112 117 [[headers]]
+47 -50
src/components/ui/FaviconThemeSwitcher.astro
··· 2 2 // Favicon theme switcher for system theme-based favicon updates 3 3 class FaviconThemeSwitcher { 4 4 constructor() { 5 - this.faviconLink = document.querySelector('link[rel="icon"]') 6 - this.currentColor = null 7 - this.init() 8 - } 5 + this.faviconLink = 6 + document.querySelector('link[rel="icon"]') || 7 + document.querySelector('link[rel="shortcut icon"]') || 8 + document.querySelector('link[rel="apple-touch-icon"]') 9 9 10 - init() { 11 - // Listen for system theme changes only 12 - this.observeSystemThemeChanges() 10 + if (!this.faviconLink) { 11 + console.warn('Favicon link not found, skipping theme switcher') 12 + return 13 + } 13 14 14 - // Set initial favicon color based on system theme 15 - this.updateFaviconForSystemTheme() 16 - } 15 + this.currentColor = null 16 + this.mediaQuery = window.matchMedia('(prefers-color-scheme: dark)') 17 17 18 - observeSystemThemeChanges() { 19 - // Listen for system theme changes using media query 20 - const mediaQuery = window.matchMedia('(prefers-color-scheme: dark)') 18 + // Listen for system theme changes 19 + this.mediaQuery.addEventListener('change', () => this.updateFavicon()) 21 20 22 - mediaQuery.addEventListener('change', () => { 23 - this.updateFaviconForSystemTheme() 24 - }) 21 + // Set initial favicon color 22 + this.updateFavicon() 25 23 } 26 24 27 - updateFaviconForSystemTheme() { 28 - // Only use system theme preference, ignore manual theme toggle 29 - const isSystemDark = window.matchMedia('(prefers-color-scheme: dark)').matches 30 - const newColor = isSystemDark ? '#ccc' : '#111' 25 + updateFavicon() { 26 + const newColor = this.mediaQuery.matches ? '#ccc' : '#111' 31 27 32 - // Only update if color has changed 33 28 if (this.currentColor !== newColor) { 34 29 this.currentColor = newColor 35 30 this.updateFaviconColor(newColor) 36 31 } 37 32 } 38 33 39 - updateFaviconColor(color) { 40 - if (!this.faviconLink) return 34 + async updateFaviconColor(color) { 35 + try { 36 + const response = await fetch(this.faviconLink.href) 37 + if (!response.ok) throw new Error(`HTTP ${response.status}`) 41 38 42 - const currentHref = this.faviconLink.href 39 + const svgText = await response.text() 40 + const parser = new DOMParser() 41 + const svgDoc = parser.parseFromString(svgText, 'image/svg+xml') 42 + const path = svgDoc.getElementById('favicon-path') 43 43 44 - fetch(currentHref) 45 - .then((response) => response.text()) 46 - .then((svgText) => { 47 - const parser = new DOMParser() 48 - const svgDoc = parser.parseFromString(svgText, 'image/svg+xml') 49 - const path = svgDoc.getElementById('favicon-path') 44 + if (path) { 45 + path.setAttribute('fill', color) 46 + const updatedSvg = new XMLSerializer().serializeToString(svgDoc) 47 + const blob = new Blob([updatedSvg], { type: 'image/svg+xml' }) 48 + this.faviconLink.href = URL.createObjectURL(blob) 49 + } else { 50 + console.warn('Favicon path element not found in SVG') 51 + } 52 + } catch (error) { 53 + console.warn('Failed to update favicon color:', error) 54 + } 55 + } 56 + } 50 57 51 - if (path) { 52 - path.setAttribute('fill', color) 53 - const serializer = new XMLSerializer() 54 - const updatedSvg = serializer.serializeToString(svgDoc) 55 - const blob = new Blob([updatedSvg], { type: 'image/svg+xml' }) 56 - const url = URL.createObjectURL(blob) 57 - this.faviconLink.href = url 58 - } 59 - }) 60 - .catch((error) => { 61 - console.warn('Failed to update favicon color:', error) 62 - }) 58 + // Initialize favicon theme switcher 59 + function init() { 60 + try { 61 + new FaviconThemeSwitcher() 62 + } catch (error) { 63 + console.warn('Failed to initialize favicon theme switcher:', error) 63 64 } 64 65 } 65 66 66 - // Initialize favicon theme switcher when DOM is ready 67 + // Initialize when DOM is ready 67 68 if (document.readyState === 'loading') { 68 - document.addEventListener('DOMContentLoaded', () => { 69 - new FaviconThemeSwitcher() 70 - }) 69 + document.addEventListener('DOMContentLoaded', init) 71 70 } else { 72 - new FaviconThemeSwitcher() 71 + init() 73 72 } 74 73 75 74 // Re-initialize on Astro page loads 76 - document.addEventListener('astro:page-load', () => { 77 - new FaviconThemeSwitcher() 78 - }) 75 + document.addEventListener('astro:page-load', init) 79 76 </script>