diff --git a/app/components/AppFooter.vue b/app/components/AppFooter.vue index ccda96c567..3a59dea60e 100644 --- a/app/components/AppFooter.vue +++ b/app/components/AppFooter.vue @@ -54,6 +54,10 @@ const footerSections = computed>(( name: t('footer.about'), href: '/about', }, + { + name: t('footer.sponsors'), + href: '/sponsors', + }, { name: t('footer.brand'), href: '/brand', diff --git a/app/composables/useCommandPaletteGlobalCommands.ts b/app/composables/useCommandPaletteGlobalCommands.ts index 49c873cf64..7b4a2b9278 100644 --- a/app/composables/useCommandPaletteGlobalCommands.ts +++ b/app/composables/useCommandPaletteGlobalCommands.ts @@ -323,6 +323,16 @@ export function useCommandPaletteGlobalCommands() { ), to: { name: 'noodles' }, }, + { + id: 'sponsors', + group: 'npmx', + label: t('sponsors_page.title'), + keywords: [t('sponsors_page.title')], + iconClass: 'i-lucide:heart', + active: route.name === 'sponsors', + activeLabel: activeLabel(route.name === 'sponsors', t('command_palette.here')), + to: { name: 'sponsors' }, + }, { id: 'brand', group: 'npmx', diff --git a/app/pages/about.vue b/app/pages/about.vue index b2263d5ae9..4432dcec4d 100644 --- a/app/pages/about.vue +++ b/app/pages/about.vue @@ -149,6 +149,11 @@ const communityContributors = computed(

{{ $t('about.sponsors.title') }}

+

+ + {{ $t('sponsors_page.cta') }} + +

{{ $t('about.sponsors.gold') }}

diff --git a/app/pages/sponsors.vue b/app/pages/sponsors.vue new file mode 100644 index 0000000000..87d265cb63 --- /dev/null +++ b/app/pages/sponsors.vue @@ -0,0 +1,250 @@ + + + + + diff --git a/i18n/locales/en.json b/i18n/locales/en.json index 34e9679053..18cde0ae95 100644 --- a/i18n/locales/en.json +++ b/i18n/locales/en.json @@ -13,6 +13,7 @@ "trademark_disclaimer": "npm is a registered trademark of npm, Inc. This site is not affiliated with npm, Inc.", "footer": { "about": "about", + "sponsors": "sponsors", "blog": "blog", "docs": "docs", "source": "source", @@ -1268,6 +1269,64 @@ } } }, + "sponsors_page": { + "title": "Sponsors", + "heading": "sponsors", + "meta_description": "Support npmx and help us accelerate ecosystem work around security, trust, optimization, and research.", + "intro": "Support npmx and help us grow the ecosystem work we do for developers and maintainers.", + "what_we_do": { + "title": "What we do", + "description": "We're building an ecosystem that solves problems around security, trust, optimization, and research for the tools we use in everyday development - quickly, conveniently, and with high quality. This project is built by developers for developers. As authors of widely used libraries, we understand team needs and actively study what maintainers and projects need most." + }, + "what_support_means": { + "title": "What support means", + "description": "Our plans and connections keep growing, along with our desire to share what we've built and learn from others. Your support helps fund the project, external talks, conferences, and the broader ecosystem, and, most importantly, enables us to keep growing our community." + }, + "cta": "See sponsorship tiers", + "community_growth_footnote": "* According to {link} Q1 2026 research.", + "what_this_means_for_you": { + "title": "What this means for you", + "description": "npmx is not only about improving developer experience and closing critical everyday gaps. In our first six months, we have already become the default source for thousands of teams and a huge number of developers. You get not only a more stable tool for your teams, but also visibility in front of a constantly growing audience of top-tier engineers.", + "cards": { + "people": { + "contributors": "contributors", + "community_members": "community members" + }, + "visitors": { + "description": "unique monthly visitors" + }, + "stars": { + "title": "stars" + }, + "community": { + "title": "fast-growing", + "description": "We have one of the fastest-growing communities in the ecosystem" + }, + "adoption": { + "title": "adoption", + "description": "charts at conferences, talks, and articles rely on our data" + }, + "default_source": { + "title": "default source", + "description": "pnpm made npmx the default source, many packages have been configured to link to npmx" + } + } + }, + "tiers": { + "title": "Sponsorship tiers", + "per_month": "/month", + "custom": "Custom", + "silver": { + "name": "Silver" + }, + "gold": { + "name": "Gold" + }, + "platinum": { + "name": "Platinum" + } + } + }, "account_menu": { "connect": "connect", "account": "Account", diff --git a/i18n/schema.json b/i18n/schema.json index 78c93bab56..1fe63c4793 100644 --- a/i18n/schema.json +++ b/i18n/schema.json @@ -43,6 +43,9 @@ "about": { "type": "string" }, + "sponsors": { + "type": "string" + }, "blog": { "type": "string" }, @@ -3808,6 +3811,180 @@ }, "additionalProperties": false }, + "sponsors_page": { + "type": "object", + "properties": { + "title": { + "type": "string" + }, + "heading": { + "type": "string" + }, + "meta_description": { + "type": "string" + }, + "intro": { + "type": "string" + }, + "what_we_do": { + "type": "object", + "properties": { + "title": { + "type": "string" + }, + "description": { + "type": "string" + } + }, + "additionalProperties": false + }, + "what_support_means": { + "type": "object", + "properties": { + "title": { + "type": "string" + }, + "description": { + "type": "string" + } + }, + "additionalProperties": false + }, + "cta": { + "type": "string" + }, + "community_growth_footnote": { + "type": "string" + }, + "what_this_means_for_you": { + "type": "object", + "properties": { + "title": { + "type": "string" + }, + "description": { + "type": "string" + }, + "cards": { + "type": "object", + "properties": { + "people": { + "type": "object", + "properties": { + "contributors": { + "type": "string" + }, + "community_members": { + "type": "string" + } + }, + "additionalProperties": false + }, + "visitors": { + "type": "object", + "properties": { + "description": { + "type": "string" + } + }, + "additionalProperties": false + }, + "stars": { + "type": "object", + "properties": { + "title": { + "type": "string" + } + }, + "additionalProperties": false + }, + "community": { + "type": "object", + "properties": { + "title": { + "type": "string" + }, + "description": { + "type": "string" + } + }, + "additionalProperties": false + }, + "adoption": { + "type": "object", + "properties": { + "title": { + "type": "string" + }, + "description": { + "type": "string" + } + }, + "additionalProperties": false + }, + "default_source": { + "type": "object", + "properties": { + "title": { + "type": "string" + }, + "description": { + "type": "string" + } + }, + "additionalProperties": false + } + }, + "additionalProperties": false + } + }, + "additionalProperties": false + }, + "tiers": { + "type": "object", + "properties": { + "title": { + "type": "string" + }, + "per_month": { + "type": "string" + }, + "custom": { + "type": "string" + }, + "silver": { + "type": "object", + "properties": { + "name": { + "type": "string" + } + }, + "additionalProperties": false + }, + "gold": { + "type": "object", + "properties": { + "name": { + "type": "string" + } + }, + "additionalProperties": false + }, + "platinum": { + "type": "object", + "properties": { + "name": { + "type": "string" + } + }, + "additionalProperties": false + } + }, + "additionalProperties": false + } + }, + "additionalProperties": false + }, "account_menu": { "type": "object", "properties": { diff --git a/nuxt.config.ts b/nuxt.config.ts index eb3d7fc36d..580f8777c8 100644 --- a/nuxt.config.ts +++ b/nuxt.config.ts @@ -216,6 +216,7 @@ export default defineNuxtConfig({ '/pds': { isr: 86400 }, // revalidate daily '/blog/**': { prerender: true }, '/noodles/**': { prerender: true }, + '/sponsors': { prerender: true }, // proxy for insights '/_v/script.js': { proxy: 'https://npmx.dev/_vercel/insights/script.js', diff --git a/server/middleware/canonical-redirects.global.ts b/server/middleware/canonical-redirects.global.ts index 32161fe483..738612c2a7 100644 --- a/server/middleware/canonical-redirects.global.ts +++ b/server/middleware/canonical-redirects.global.ts @@ -22,6 +22,7 @@ const pages = [ '/brand', '/compare', '/noodles', + '/sponsors', '/org', '/package', '/package-code',