feat: add local fallback for flag-icons CSS

- Download flag-icons CSS and SVG sprites for supported languages (gb, fr, de, lu)
- Add onerror fallback to all base templates (admin, vendor, shop)
- CDN loads first, falls back to local copy if unavailable

This ensures the language selector flags work even when CDN is blocked
or unavailable.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
2025-12-13 23:13:43 +01:00
parent bd93a17e2b
commit 619c650598
12 changed files with 63 additions and 6 deletions

View File

@@ -13,8 +13,12 @@
<!-- Tailwind CSS v4 (built locally via standalone CLI) -->
<link rel="stylesheet" href="{{ url_for('static', path='admin/css/tailwind.output.css') }}" />
<!-- Flag Icons CSS (for language selector) -->
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/flag-icons@7.2.3/css/flag-icons.min.css" />
<!-- Flag Icons CSS (for language selector) with local fallback -->
<link
rel="stylesheet"
href="https://cdn.jsdelivr.net/npm/flag-icons@7.2.3/css/flag-icons.min.css"
onerror="this.onerror=null; this.href='{{ url_for('static', path='shared/css/vendor/flag-icons.min.css') }}';"
/>
<!-- Alpine Cloak -->
<style>

View File

@@ -40,8 +40,12 @@
{# Tailwind CSS v4 (built locally via standalone CLI) #}
<link rel="stylesheet" href="{{ url_for('static', path='shop/css/tailwind.output.css') }}">
{# Flag Icons for Language Selector #}
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/flag-icons@7.2.3/css/flag-icons.min.css" />
{# Flag Icons for Language Selector with local fallback #}
<link
rel="stylesheet"
href="https://cdn.jsdelivr.net/npm/flag-icons@7.2.3/css/flag-icons.min.css"
onerror="this.onerror=null; this.href='{{ url_for('static', path='shared/css/vendor/flag-icons.min.css') }}';"
/>
{# Base Shop Styles #}
<link rel="stylesheet" href="{{ url_for('static', path='shop/css/shop.css') }}">

View File

@@ -13,8 +13,12 @@
<!-- Tailwind CSS v4 (built locally via standalone CLI) -->
<link rel="stylesheet" href="{{ url_for('static', path='vendor/css/tailwind.output.css') }}" />
<!-- Flag Icons for Language Selector -->
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/flag-icons@7.2.3/css/flag-icons.min.css" />
<!-- Flag Icons for Language Selector with local fallback -->
<link
rel="stylesheet"
href="https://cdn.jsdelivr.net/npm/flag-icons@7.2.3/css/flag-icons.min.css"
onerror="this.onerror=null; this.href='{{ url_for('static', path='shared/css/vendor/flag-icons.min.css') }}';"
/>
<!-- Alpine Cloak -->
<style>

View File

@@ -0,0 +1,5 @@
<svg xmlns="http://www.w3.org/2000/svg" id="flag-icons-de" viewBox="0 0 512 512">
<path fill="#fc0" d="M0 341.3h512V512H0z"/>
<path fill="#000001" d="M0 0h512v170.7H0z"/>
<path fill="red" d="M0 170.7h512v170.6H0z"/>
</svg>

After

Width:  |  Height:  |  Size: 229 B

View File

@@ -0,0 +1,5 @@
<svg xmlns="http://www.w3.org/2000/svg" id="flag-icons-fr" viewBox="0 0 512 512">
<path fill="#fff" d="M0 0h512v512H0z"/>
<path fill="#000091" d="M0 0h170.7v512H0z"/>
<path fill="#e1000f" d="M341.3 0H512v512H341.3z"/>
</svg>

After

Width:  |  Height:  |  Size: 231 B

View File

@@ -0,0 +1,7 @@
<svg xmlns="http://www.w3.org/2000/svg" id="flag-icons-gb" viewBox="0 0 512 512">
<path fill="#012169" d="M0 0h512v512H0z"/>
<path fill="#FFF" d="M512 0v64L322 256l190 187v69h-67L254 324 68 512H0v-68l186-187L0 74V0h62l192 188L440 0z"/>
<path fill="#C8102E" d="m184 324 11 34L42 512H0v-3zm124-12 54 8 150 147v45zM512 0 320 196l-4-44L466 0zM0 1l193 189-59-8L0 49z"/>
<path fill="#FFF" d="M176 0v512h160V0zM0 176v160h512V176z"/>
<path fill="#C8102E" d="M0 208v96h512v-96zM208 0v512h96V0z"/>
</svg>

After

Width:  |  Height:  |  Size: 505 B

View File

@@ -0,0 +1,5 @@
<svg xmlns="http://www.w3.org/2000/svg" id="flag-icons-lu" viewBox="0 0 512 512">
<path fill="#ed2939" d="M0 0h512v170.7H0z"/>
<path fill="#fff" d="M0 170.7h512v170.6H0z"/>
<path fill="#00a1de" d="M0 341.3h512V512H0z"/>
</svg>

After

Width:  |  Height:  |  Size: 233 B

View File

@@ -0,0 +1,5 @@
<svg xmlns="http://www.w3.org/2000/svg" id="flag-icons-de" viewBox="0 0 640 480">
<path fill="#fc0" d="M0 320h640v160H0z"/>
<path fill="#000001" d="M0 0h640v160H0z"/>
<path fill="red" d="M0 160h640v160H0z"/>
</svg>

After

Width:  |  Height:  |  Size: 221 B

View File

@@ -0,0 +1,5 @@
<svg xmlns="http://www.w3.org/2000/svg" id="flag-icons-fr" viewBox="0 0 640 480">
<path fill="#fff" d="M0 0h640v480H0z"/>
<path fill="#000091" d="M0 0h213.3v480H0z"/>
<path fill="#e1000f" d="M426.7 0H640v480H426.7z"/>
</svg>

After

Width:  |  Height:  |  Size: 231 B

View File

@@ -0,0 +1,7 @@
<svg xmlns="http://www.w3.org/2000/svg" id="flag-icons-gb" viewBox="0 0 640 480">
<path fill="#012169" d="M0 0h640v480H0z"/>
<path fill="#FFF" d="m75 0 244 181L562 0h78v62L400 241l240 178v61h-80L320 301 81 480H0v-60l239-178L0 64V0z"/>
<path fill="#C8102E" d="m424 281 216 159v40L369 281zm-184 20 6 35L54 480H0zM640 0v3L391 191l2-44L590 0zM0 0l239 176h-60L0 42z"/>
<path fill="#FFF" d="M241 0v480h160V0zM0 160v160h640V160z"/>
<path fill="#C8102E" d="M0 193v96h640v-96zM273 0v480h96V0z"/>
</svg>

After

Width:  |  Height:  |  Size: 504 B

View File

@@ -0,0 +1,5 @@
<svg xmlns="http://www.w3.org/2000/svg" id="flag-icons-lu" viewBox="0 0 640 480">
<path fill="#ed2939" d="M0 0h640v160H0z"/>
<path fill="#fff" d="M0 160h640v160H0z"/>
<path fill="#00a1de" d="M0 320h640v160H0z"/>
</svg>

After

Width:  |  Height:  |  Size: 225 B

File diff suppressed because one or more lines are too long