Skip to content

Commit c062ad6

Browse files
Felix SchneiderFelix Schneider
authored andcommitted
feat(docs): add custom badge generator
1 parent 5d8fcf5 commit c062ad6

File tree

3 files changed

+213
-114
lines changed

3 files changed

+213
-114
lines changed
Lines changed: 101 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,101 @@
1+
<script setup>
2+
const pkg = useState('badge-pkg', () => 'nuxt')
3+
const type = useState('badge-type', () => 'version')
4+
const isValid = ref(true)
5+
const copied = ref(false)
6+
7+
const types = [
8+
'version',
9+
'license',
10+
'size',
11+
'downloads',
12+
'downloads-day',
13+
'downloads-week',
14+
'downloads-month',
15+
'downloads-year',
16+
'vulnerabilities',
17+
'dependencies',
18+
'created',
19+
'updated',
20+
'engines',
21+
'types',
22+
'maintainers',
23+
'deprecated',
24+
'quality',
25+
'popularity',
26+
'maintenance',
27+
'score',
28+
'name'
29+
]
30+
31+
watch(pkg, () => {
32+
isValid.value = true
33+
})
34+
35+
const copyToClipboard = async () => {
36+
const markdown = `[![Open on npmx.dev](https://npmx.dev/api/registry/badge/${type.value}/${pkg.value})](https://npmx.dev/package/${pkg.value})`
37+
await navigator.clipboard.writeText(markdown)
38+
39+
copied.value = true
40+
setTimeout(() => {
41+
copied.value = false
42+
}, 2000)
43+
}
44+
</script>
45+
46+
<template>
47+
<div class="my-8 p-5 rounded-xl border border-gray-200/60 dark:border-white/5 bg-gray-50/50 dark:bg-white/[0.02] flex flex-col sm:flex-row items-end gap-4">
48+
49+
<div class="flex flex-col gap-1.5 flex-1 w-full">
50+
<label class="text-[11px] font-bold uppercase tracking-wider text-gray-400 ml-1">Package Name</label>
51+
<input
52+
v-model="pkg"
53+
type="text"
54+
spellcheck="false"
55+
class="w-full h-[42px] px-4 py-2 rounded-lg border border-gray-200 dark:border-white/10 bg-white dark:bg-black/20 focus:ring-2 focus:ring-emerald-500/20 focus:border-emerald-500 outline-none text-sm transition-all"
56+
:class="{ 'border-red-500/50 focus:ring-red-500/10 focus:border-red-500': !isValid }"
57+
placeholder="e.g. nuxt"
58+
/>
59+
</div>
60+
61+
<div class="flex flex-col gap-1.5 flex-1 w-full">
62+
<label class="text-[11px] font-bold uppercase tracking-wider text-gray-400 ml-1">Badge Type</label>
63+
<div class="relative">
64+
<select
65+
v-model="type"
66+
class="w-full h-[42px] px-4 py-2 rounded-lg border border-gray-200 dark:border-white/10 bg-white dark:bg-black/20 focus:ring-2 focus:ring-emerald-500/20 focus:border-emerald-500 outline-none text-sm transition-all appearance-none cursor-pointer"
67+
>
68+
<option v-for="t in types" :key="t" :value="t" class="dark:bg-gray-900">{{ t }}</option>
69+
</select>
70+
<span class="absolute right-3 top-1/2 -translate-y-1/2 i-lucide-chevron-down w-4 h-4 text-gray-400 pointer-events-none" />
71+
</div>
72+
</div>
73+
74+
<div class="flex flex-col gap-1.5 flex-2 w-full">
75+
<label class="text-[11px] font-bold uppercase tracking-wider text-gray-400 ml-1">Preview & Action</label>
76+
<div class="flex items-center bg-white dark:bg-black/20 border border-gray-200 dark:border-white/10 rounded-lg h-[42px] overflow-hidden">
77+
78+
<div class="flex-1 flex items-center justify-center px-3 border-r border-gray-200 dark:border-white/10 h-full bg-gray-50/50 dark:bg-transparent">
79+
<img
80+
v-if="isValid"
81+
:src="`https://npmx.dev/api/registry/badge/${type}/${pkg}`"
82+
class="h-[20px]"
83+
alt="Badge Preview"
84+
@error="isValid = false"
85+
/>
86+
<span v-else class="text-[10px] font-bold text-red-500 uppercase tracking-tighter">Invalid</span>
87+
</div>
88+
89+
<button
90+
@click="copyToClipboard"
91+
:disabled="!isValid"
92+
class="px-4 h-full text-[11px] font-bold uppercase tracking-widest transition-all disabled:opacity-20 disabled:cursor-not-allowed min-w-[85px] hover:bg-gray-50 dark:hover:bg-white/5"
93+
:class="copied ? 'text-emerald-500 bg-emerald-50/50 dark:bg-emerald-500/10' : 'text-gray-500 dark:text-gray-400'"
94+
>
95+
{{ copied ? 'Done!' : 'Copy' }}
96+
</button>
97+
</div>
98+
</div>
99+
100+
</div>
101+
</template>

docs/content/2.guide/1.features.md

Lines changed: 0 additions & 114 deletions
Original file line numberDiff line numberDiff line change
@@ -88,117 +88,3 @@ Quick access to online development environments detected from package READMEs:
8888
| :icon{name="i-lucide:pen-tool"} [CodePen](https://codepen.io) | Social development environment for front-end |
8989
| :icon{name="i-simple-icons-jsfiddle"} [JSFiddle](https://jsfiddle.net) | Online editor for web snippets |
9090
| :icon{name="i-simple-icons-replit"} [Replit](https://replit.com) | Collaborative browser-based IDE |
91-
92-
### Custom badges
93-
94-
You can add custom npmx badges to your markdown files using the following syntax:
95-
96-
```md
97-
[![Open on npmx.dev](https://npmx.dev/api/registry/badge/TYPE/YOUR_PACKAGE)](https://npmx.dev/package/YOUR_PACKAGE)
98-
```
99-
100-
::tip
101-
Make sure to replace `TYPE` with one of the options listed below and `YOUR_PACKAGE` with the actual package name (e.g., `vue`, `lodash`, or `@nuxt/kit`).
102-
::
103-
104-
#### Available Badge Types
105-
106-
- **version**: Shows the latest or specific version of the package. :img{src="https://img.shields.io/badge/%233b82f6-3b82f6" class="inline align-middle h-5 w-14"}
107-
- **license**: Displays the package license (e.g., MIT, Apache-2.0). :img{src="https://img.shields.io/badge/%2322c55e-22c55e" class="inline align-middle h-5 w-14"}
108-
- **size**: Shows the install size (via Bundlephobia) or unpacked size. :img{src="https://img.shields.io/badge/%23a855f7-a855f7" class="inline align-middle h-5 w-14"}
109-
- **downloads**: Displays monthly download statistics. :img{src="https://img.shields.io/badge/%23f97316-f97316" class="inline align-middle h-5 w-14"}
110-
- **downloads-day**: Displays daily download statistics. :img{src="https://img.shields.io/badge/%23f97316-f97316" class="inline align-middle h-5 w-14"}
111-
- **downloads-week**: Displays weekly download statistics. :img{src="https://img.shields.io/badge/%23f97316-f97316" class="inline align-middle h-5 w-14"}
112-
- **downloads-month**: Alias for monthly download statistics. :img{src="https://img.shields.io/badge/%23f97316-f97316" class="inline align-middle h-5 w-14"}
113-
- **downloads-year**: Displays yearly download statistics. :img{src="https://img.shields.io/badge/%23f97316-f97316" class="inline align-middle h-5 w-14"}
114-
- **vulnerabilities**: Shows the number of vulnerabilities found via OSV. :img{src="https://img.shields.io/badge/%2322c55e-22c55e" class="inline align-middle h-5 w-14"} / :img{src="https://img.shields.io/badge/%23ef4444-ef4444" class="inline align-middle h-5 w-14"}
115-
- **dependencies**: Lists the total count of package dependencies. :img{src="https://img.shields.io/badge/%2306b6d4-06b6d4" class="inline align-middle h-5 w-14"}
116-
- **created**: Displays the date the package was first published. :img{src="https://img.shields.io/badge/%2364748b-64748b" class="inline align-middle h-5 w-14"}
117-
- **updated**: Displays the date of the most recent modification. :img{src="https://img.shields.io/badge/%2364748b-64748b" class="inline align-middle h-5 w-14"}
118-
- **engines**: Shows the supported Node.js version range. :img{src="https://img.shields.io/badge/%23eab308-eab308" class="inline align-middle h-5 w-14"}
119-
- **types**: Indicates if TypeScript types are included. :img{src="https://img.shields.io/badge/%233b82f6-3b82f6" class="inline align-middle h-5 w-14"} / :img{src="https://img.shields.io/badge/%2364748b-64748b" class="inline align-middle h-5 w-14"}
120-
- **maintainers**: Displays the total count of package maintainers. :img{src="https://img.shields.io/badge/%2306b6d4-06b6d4" class="inline align-middle h-5 w-14"}
121-
- **deprecated**: Shows if the package is active or deprecated. :img{src="https://img.shields.io/badge/%2322c55e-22c55e" class="inline align-middle h-5 w-14"} / :img{src="https://img.shields.io/badge/%23ef4444-ef4444" class="inline align-middle h-5 w-14"}
122-
- **quality**: NPMS.io quality score based on linting and tests. :img{src="https://img.shields.io/badge/%23a855f7-a855f7" class="inline align-middle h-5 w-14"}
123-
- **popularity**: NPMS.io popularity score based on downloads and stars. :img{src="https://img.shields.io/badge/%2306b6d4-06b6d4" class="inline align-middle h-5 w-14"}
124-
- **maintenance**: NPMS.io maintenance score based on activity. :img{src="https://img.shields.io/badge/%23eab308-eab308" class="inline align-middle h-5 w-14"}
125-
- **score**: The overall NPMS.io combined score. :img{src="https://img.shields.io/badge/%233b82f6-3b82f6" class="inline align-middle h-5 w-14"}
126-
- **name**: Simple badge displaying the package name. :img{src="https://img.shields.io/badge/%2364748b-64748b" class="inline align-middle h-5 w-14"}
127-
128-
#### Examples
129-
130-
```md
131-
# Version Badge
132-
133-
[![Open on npmx.dev](https://npmx.dev/api/registry/badge/version/nuxt)](https://npmx.dev/package/nuxt)
134-
135-
# License Badge
136-
137-
[![Open on npmx.dev](https://npmx.dev/api/registry/badge/license/vue)](https://npmx.dev/package/vue)
138-
139-
# Monthly Downloads
140-
141-
[![Open on npmx.dev](https://npmx.dev/api/registry/badge/downloads/lodash)](https://npmx.dev/package/lodash)
142-
143-
# Scoped Package (Install Size)
144-
145-
[![Open on npmx.dev](https://npmx.dev/api/registry/badge/size/@nuxt/kit)](https://npmx.dev/package/@nuxt/kit)
146-
147-
# Specific Version
148-
149-
[![Open on npmx.dev](https://npmx.dev/api/registry/badge/version/react/v/18.0.0)](https://npmx.dev/package/react)
150-
151-
# Quality Score
152-
153-
[![Open on npmx.dev](https://npmx.dev/api/registry/badge/quality/pinia)](https://npmx.dev/package/pinia)
154-
```
155-
156-
#### Customization Parameters
157-
158-
You can further customize your badges by appending query parameters to the badge URL.
159-
160-
##### `labelColor`
161-
162-
Overrides the default label color. You can pass a standard hex code (with or without the `#` prefix). The label text color is automatically chosen (black or white) based on WCAG contrast ratio, so the badge remains readable.
163-
164-
- **Default**: `#0a0a0a`
165-
- **Usage**: `?labelColor=HEX_CODE`
166-
167-
##### `label`
168-
169-
Overrides the default label text. You can pass any string to customize the label displayed on the badge.
170-
171-
- **Default**: Depends on the badge type (e.g., "version", "downloads/mo").
172-
- **Usage**: `?label=YOUR_LABEL`
173-
174-
##### `color`
175-
176-
Overrides the default strategy color. You can pass a standard hex code (with or without the `#` prefix). The text color is automatically chosen (black or white) based on WCAG contrast ratio, so the badge remains readable.
177-
178-
- **Default**: Depends on the badge type (e.g., version is blue, downloads are orange).
179-
- **Usage**: `?color=HEX_CODE`
180-
181-
| Example | URL |
182-
| :------------- | :------------------------------------ |
183-
| **Hot Pink** | `.../badge/version/nuxt?color=ff69b4` |
184-
| **Pure Black** | `.../badge/version/nuxt?color=000000` |
185-
| **Brand Blue** | `.../badge/version/nuxt?color=3b82f6` |
186-
187-
##### `name`
188-
189-
When set to `true`, this parameter replaces the static category label (like "version" or "downloads/mo") with the actual name of the package. This is useful for brand-focused READMEs.
190-
191-
- **Default**: `false`
192-
- **Usage**: `?name=true`
193-
194-
| Type | Default Label | With `name=true` |
195-
| ------------- | -------------------- | ---------------- |
196-
| **Version** | `version \| 3.12.0` | `nuxt \| 3.12.0` |
197-
| **Downloads** | `downloads/mo \| 2M` | `lodash \| 2M` |
198-
199-
##### `style`
200-
201-
Overrides the default badge appearance. Pass `shieldsio` to use the shields.io-compatible style.
202-
203-
- **Default**: `default`
204-
- **Usage**: `?style=shieldsio`

docs/content/2.guide/6.badges.md

Lines changed: 112 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,112 @@
1+
---
2+
title: Badges
3+
description: Generate modern markdown badges with the npmx.dev API
4+
navigation:
5+
icon: i-lucide:badge
6+
---
7+
8+
npmx.dev offers many different SVG badges with stats about any package via its API. You can get the Markdown code to display an accessible badge which links to the package URL on npmx.dev with the following interactive generator:
9+
10+
:badge-generator
11+
12+
## Available Badge Types
13+
14+
- **version**: Shows the latest or specific version of the package. :img{src="https://img.shields.io/badge/%233b82f6-3b82f6" class="inline align-middle h-5 w-14"}
15+
- **license**: Displays the package license (e.g., MIT, Apache-2.0). :img{src="https://img.shields.io/badge/%2322c55e-22c55e" class="inline align-middle h-5 w-14"}
16+
- **size**: Shows the install size (via Bundlephobia) or unpacked size. :img{src="https://img.shields.io/badge/%23a855f7-a855f7" class="inline align-middle h-5 w-14"}
17+
- **downloads**: Displays monthly download statistics. :img{src="https://img.shields.io/badge/%23f97316-f97316" class="inline align-middle h-5 w-14"}
18+
- **downloads-day**: Displays daily download statistics. :img{src="https://img.shields.io/badge/%23f97316-f97316" class="inline align-middle h-5 w-14"}
19+
- **downloads-week**: Displays weekly download statistics. :img{src="https://img.shields.io/badge/%23f97316-f97316" class="inline align-middle h-5 w-14"}
20+
- **downloads-month**: Alias for monthly download statistics. :img{src="https://img.shields.io/badge/%23f97316-f97316" class="inline align-middle h-5 w-14"}
21+
- **downloads-year**: Displays yearly download statistics. :img{src="https://img.shields.io/badge/%23f97316-f97316" class="inline align-middle h-5 w-14"}
22+
- **vulnerabilities**: Shows the number of vulnerabilities found via OSV. :img{src="https://img.shields.io/badge/%2322c55e-22c55e" class="inline align-middle h-5 w-14"} / :img{src="https://img.shields.io/badge/%23ef4444-ef4444" class="inline align-middle h-5 w-14"}
23+
- **dependencies**: Lists the total count of package dependencies. :img{src="https://img.shields.io/badge/%2306b6d4-06b6d4" class="inline align-middle h-5 w-14"}
24+
- **created**: Displays the date the package was first published. :img{src="https://img.shields.io/badge/%2364748b-64748b" class="inline align-middle h-5 w-14"}
25+
- **updated**: Displays the date of the most recent modification. :img{src="https://img.shields.io/badge/%2364748b-64748b" class="inline align-middle h-5 w-14"}
26+
- **engines**: Shows the supported Node.js version range. :img{src="https://img.shields.io/badge/%23eab308-eab308" class="inline align-middle h-5 w-14"}
27+
- **types**: Indicates if TypeScript types are included. :img{src="https://img.shields.io/badge/%233b82f6-3b82f6" class="inline align-middle h-5 w-14"} / :img{src="https://img.shields.io/badge/%2364748b-64748b" class="inline align-middle h-5 w-14"}
28+
- **maintainers**: Displays the total count of package maintainers. :img{src="https://img.shields.io/badge/%2306b6d4-06b6d4" class="inline align-middle h-5 w-14"}
29+
- **deprecated**: Shows if the package is active or deprecated. :img{src="https://img.shields.io/badge/%2322c55e-22c55e" class="inline align-middle h-5 w-14"} / :img{src="https://img.shields.io/badge/%23ef4444-ef4444" class="inline align-middle h-5 w-14"}
30+
- **quality**: NPMS.io quality score based on linting and tests. :img{src="https://img.shields.io/badge/%23a855f7-a855f7" class="inline align-middle h-5 w-14"}
31+
- **popularity**: NPMS.io popularity score based on downloads and stars. :img{src="https://img.shields.io/badge/%2306b6d4-06b6d4" class="inline align-middle h-5 w-14"}
32+
- **maintenance**: NPMS.io maintenance score based on activity. :img{src="https://img.shields.io/badge/%23eab308-eab308" class="inline align-middle h-5 w-14"}
33+
- **score**: The overall NPMS.io combined score. :img{src="https://img.shields.io/badge/%233b82f6-3b82f6" class="inline align-middle h-5 w-14"}
34+
- **name**: Simple badge displaying the package name. :img{src="https://img.shields.io/badge/%2364748b-64748b" class="inline align-middle h-5 w-14"}
35+
36+
## Examples
37+
38+
```md
39+
# Version Badge
40+
41+
[![Open on npmx.dev](https://npmx.dev/api/registry/badge/version/nuxt)](https://npmx.dev/package/nuxt)
42+
43+
# License Badge
44+
45+
[![Open on npmx.dev](https://npmx.dev/api/registry/badge/license/vue)](https://npmx.dev/package/vue)
46+
47+
# Monthly Downloads
48+
49+
[![Open on npmx.dev](https://npmx.dev/api/registry/badge/downloads/lodash)](https://npmx.dev/package/lodash)
50+
51+
# Scoped Package (Install Size)
52+
53+
[![Open on npmx.dev](https://npmx.dev/api/registry/badge/size/@nuxt/kit)](https://npmx.dev/package/@nuxt/kit)
54+
55+
# Specific Version
56+
57+
[![Open on npmx.dev](https://npmx.dev/api/registry/badge/version/react/v/18.0.0)](https://npmx.dev/package/react)
58+
59+
# Quality Score
60+
61+
[![Open on npmx.dev](https://npmx.dev/api/registry/badge/quality/pinia)](https://npmx.dev/package/pinia)
62+
```
63+
64+
## Customization Parameters
65+
66+
You can further customize your badges by appending query parameters to the badge URL.
67+
68+
### `labelColor`
69+
70+
Overrides the default label color. You can pass a standard hex code (with or without the `#` prefix). The label text color is automatically chosen (black or white) based on WCAG contrast ratio, so the badge remains readable.
71+
72+
- **Default**: `#0a0a0a`
73+
- **Usage**: `?labelColor=HEX_CODE`
74+
75+
### `label`
76+
77+
Overrides the default label text. You can pass any string to customize the label displayed on the badge.
78+
79+
- **Default**: Depends on the badge type (e.g., "version", "downloads/mo").
80+
- **Usage**: `?label=YOUR_LABEL`
81+
82+
### `color`
83+
84+
Overrides the default strategy color. You can pass a standard hex code (with or without the `#` prefix). The text color is automatically chosen (black or white) based on WCAG contrast ratio, so the badge remains readable.
85+
86+
- **Default**: Depends on the badge type (e.g., version is blue, downloads are orange).
87+
- **Usage**: `?color=HEX_CODE`
88+
89+
| Example | URL |
90+
| :------------- | :------------------------------------ |
91+
| **Hot Pink** | `.../badge/version/nuxt?color=ff69b4` |
92+
| **Pure Black** | `.../badge/version/nuxt?color=000000` |
93+
| **Brand Blue** | `.../badge/version/nuxt?color=3b82f6` |
94+
95+
### `name`
96+
97+
When set to `true`, this parameter replaces the static category label (like "version" or "downloads/mo") with the actual name of the package. This is useful for brand-focused READMEs.
98+
99+
- **Default**: `false`
100+
- **Usage**: `?name=true`
101+
102+
| Type | Default Label | With `name=true` |
103+
| ------------- | -------------------- | ---------------- |
104+
| **Version** | `version \| 3.12.0` | `nuxt \| 3.12.0` |
105+
| **Downloads** | `downloads/mo \| 2M` | `lodash \| 2M` |
106+
107+
### `style`
108+
109+
Overrides the default badge appearance. Pass `shieldsio` to use the shields.io-compatible style.
110+
111+
- **Default**: `default`
112+
- **Usage**: `?style=shieldsio`

0 commit comments

Comments
 (0)