Skip to content

Commit 67393b3

Browse files
author
Jeff Dickey
committed
docs: add sponsors page
1 parent 534b00f commit 67393b3

2 files changed

Lines changed: 84 additions & 1 deletion

File tree

docs/.vitepress/config.mts

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -113,7 +113,10 @@ export default defineConfig({
113113
{
114114
text: "Resources",
115115
collapsed: true,
116-
items: [{ text: "Troubleshooting", link: "/troubleshooting" }],
116+
items: [
117+
{ text: "Troubleshooting", link: "/troubleshooting" },
118+
{ text: "Sponsors", link: "/sponsors" },
119+
],
117120
},
118121
],
119122

docs/sponsors.md

Lines changed: 80 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,80 @@
1+
---
2+
title: Sponsors
3+
description: Companies supporting the en.dev open source project family.
4+
---
5+
6+
<script setup>
7+
import { computed, onMounted, ref } from "vue";
8+
9+
const feed = ref(null);
10+
const error = ref("");
11+
const tiers = [["anchor", "Anchor"], ["premier", "Premier"], ["partner", "Partner"], ["backer", "Backer"]];
12+
13+
onMounted(async () => {
14+
try {
15+
const res = await fetch("https://en.dev/sponsors.json");
16+
if (!res.ok) throw new Error(`HTTP ${res.status}`);
17+
feed.value = await res.json();
18+
} catch (err) {
19+
error.value = err?.message || "Unable to load sponsors";
20+
}
21+
});
22+
23+
const paidSponsors = computed(() => (feed.value?.paid || feed.value?.sponsors || []).filter((s) => s.name && s.url));
24+
const sponsorsByTier = computed(() => tiers.map(([id, label]) => ({ id, label, sponsors: paidSponsors.value.filter((s) => s.tier === id) })));
25+
const otherSponsors = computed(() => paidSponsors.value.filter((s) => !tiers.some(([id]) => id === s.tier)));
26+
const infrastructureSponsors = computed(() => (feed.value?.infrastructure || []).filter((s) => s.name && s.url));
27+
</script>
28+
29+
# Sponsors
30+
31+
These companies support the en.dev open source project family.
32+
33+
<div v-if="error" class="sponsors-note">
34+
Sponsor data could not be loaded. Visit <a href="https://en.dev/sponsor.html">en.dev sponsors</a>.
35+
</div>
36+
<div v-else-if="!feed" class="sponsors-note">Loading sponsors...</div>
37+
<div v-else>
38+
<section v-for="tier in sponsorsByTier" :key="tier.id" class="sponsor-tier">
39+
<h2>{{ tier.label }}</h2>
40+
<div v-if="tier.sponsors.length" class="sponsor-grid">
41+
<a v-for="sponsor in tier.sponsors" :key="sponsor.name" class="sponsor-card" :href="sponsor.url" target="_blank" rel="noopener noreferrer">
42+
<img v-if="sponsor.logo" :src="sponsor.logo" :alt="sponsor.name">
43+
<span>{{ sponsor.name }}</span>
44+
</a>
45+
</div>
46+
<p v-else class="sponsors-note">No sponsors at this tier yet.</p>
47+
</section>
48+
<section v-if="otherSponsors.length" class="sponsor-tier">
49+
<h2>Other Sponsors</h2>
50+
<div class="sponsor-grid">
51+
<a v-for="sponsor in otherSponsors" :key="sponsor.name" class="sponsor-card" :href="sponsor.url" target="_blank" rel="noopener noreferrer">
52+
<img v-if="sponsor.logo" :src="sponsor.logo" :alt="sponsor.name">
53+
<span>{{ sponsor.name }}</span>
54+
</a>
55+
</div>
56+
</section>
57+
<section v-if="infrastructureSponsors.length" class="sponsor-tier">
58+
<h2>Infrastructure Partners</h2>
59+
<div class="sponsor-grid">
60+
<a v-for="sponsor in infrastructureSponsors" :key="sponsor.name" class="sponsor-card" :href="sponsor.url" target="_blank" rel="noopener noreferrer">
61+
<img v-if="sponsor.logo" :src="sponsor.logo" :alt="sponsor.name">
62+
<span>{{ sponsor.name }}</span>
63+
<small v-if="sponsor.note">{{ sponsor.note }}</small>
64+
</a>
65+
</div>
66+
</section>
67+
</div>
68+
69+
Want to support the work? [Become a sponsor](https://en.dev/sponsor.html).
70+
71+
<style>
72+
.sponsors-note { color: var(--vp-c-text-2); }
73+
.sponsor-tier { margin-top: 2rem; }
74+
.sponsor-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(180px, 1fr)); gap: 0.75rem; }
75+
.sponsor-card { min-height: 96px; border: 1px solid var(--vp-c-divider); border-radius: 8px; padding: 1rem; display: flex; flex-direction: column; align-items: flex-start; justify-content: center; gap: 0.55rem; color: var(--vp-c-text-1); background: var(--vp-c-bg-soft); text-decoration: none; }
76+
.sponsor-card:hover { border-color: var(--vp-c-brand-1); text-decoration: none; }
77+
.sponsor-card img { max-width: 150px; max-height: 36px; object-fit: contain; }
78+
.sponsor-card span { font-weight: 600; }
79+
.sponsor-card small { color: var(--vp-c-text-2); }
80+
</style>

0 commit comments

Comments
 (0)