Add the official social marks to the footer links

The marks come from the simple-icons package (CC0) and are inlined at build
time — the earlier hand-drawn glyphs were wrong, the X mark in particular is
not a plain cross. Importing the three SVGs individually rather than the
package index keeps the other icons out of the bundle: 10 kB, not 5 MB.

Rendered monochrome in the surrounding text colour, with the text label kept
next to each one.
This commit is contained in:
2026-08-25 16:11:14 +02:00
parent 0229960a15
commit abeabb3a44
4 changed files with 79 additions and 1 deletions
+38
View File
@@ -0,0 +1,38 @@
<script setup lang="ts">
// The official brand marks, inlined at build time from the simple-icons
// package (CC0) rather than redrawn here. Importing the three files directly
// keeps the other ~3000 icons out of the bundle.
import facebookMark from 'simple-icons/icons/facebook.svg?raw'
import instagramMark from 'simple-icons/icons/instagram.svg?raw'
import xMark from 'simple-icons/icons/x.svg?raw'
const MARKS = {
X: xMark,
Instagram: instagramMark,
Facebook: facebookMark,
} as const
const props = defineProps<{ name: keyof typeof MARKS }>()
const mark = computed(() => MARKS[props.name])
</script>
<template>
<!-- eslint-disable-next-line vue/no-v-html -- build-time asset, not user input -->
<span class="icon" aria-hidden="true" v-html="mark" />
</template>
<style scoped>
.icon {
flex: none;
display: inline-flex;
width: 0.95rem;
height: 0.95rem;
}
.icon :deep(svg) {
width: 100%;
height: 100%;
fill: currentColor;
}
</style>
+20 -1
View File
@@ -77,7 +77,10 @@ const { data: categories } = await useFetch<Category[]>('/api/categories', {
<p class="kicker">{{ $t('site.follow') }}</p>
<ul>
<li v-for="social in SOCIAL_LINKS" :key="social.name">
<a :href="social.url" target="_blank" rel="noopener me">{{ social.name }}</a>
<a class="social" :href="social.url" target="_blank" rel="noopener me">
<SocialIcon :name="social.name" />
<span>{{ social.name }}</span>
</a>
</li>
</ul>
</nav>
@@ -224,6 +227,22 @@ const { data: categories } = await useFetch<Category[]>('/api/categories', {
text-underline-offset: 0.2em;
}
.social {
display: inline-flex;
align-items: center;
gap: 0.55rem;
}
/* Keep the underline on the label, not stretched across the icon. */
.social:hover {
text-decoration: none;
}
.social:hover span {
text-decoration: underline;
text-underline-offset: 0.2em;
}
.copyright {
padding-top: 1.75rem;
text-align: center;
+20
View File
@@ -10,6 +10,7 @@
"@nuxtjs/i18n": "^10.6.0",
"marked": "^18.0.11",
"nuxt": "^4.5.2",
"simple-icons": "^16.28.0",
"vue": "^3.5.41",
"vue-router": "^5.2.0"
},
@@ -10241,6 +10242,25 @@
"url": "https://github.com/steveukx/git-js?sponsor=1"
}
},
"node_modules/simple-icons": {
"version": "16.28.0",
"resolved": "https://registry.npmjs.org/simple-icons/-/simple-icons-16.28.0.tgz",
"integrity": "sha512-sQPR5AtK/ijRjou7zw7mlLp08oB6FH7i0lOy5XJ2zp9mJs/yejgiOn7KvQoe2q4YJIx6VmgUSW5AOefebPt5kg==",
"funding": [
{
"type": "opencollective",
"url": "https://opencollective.com/simple-icons"
},
{
"type": "github",
"url": "https://github.com/sponsors/simple-icons"
}
],
"license": "CC0-1.0",
"engines": {
"node": ">=0.12.18"
}
},
"node_modules/sirv": {
"version": "3.0.2",
"resolved": "https://registry.npmjs.org/sirv/-/sirv-3.0.2.tgz",
+1
View File
@@ -14,6 +14,7 @@
"@nuxtjs/i18n": "^10.6.0",
"marked": "^18.0.11",
"nuxt": "^4.5.2",
"simple-icons": "^16.28.0",
"vue": "^3.5.41",
"vue-router": "^5.2.0"
},