Tool to generate icons for use in CoMapeo, or any other tool. Currently, the tool generates icons in
4.6K
Search, colorize, and export SVG icons for CoMapeo configurations.
Translate search terms into 7 languages, find icons across multiple providers, recolor them on the fly, and download ready-to-use SVG data URIs.
Live Demo
·
Report Bug
·
Request Feature
CoMapeo Icons is a web application that bridges the gap between finding the right icon and having it ready for use in CoMapeo configurations. It enables communities — especially those working in environmental monitoring and indigenous land rights — to create visually meaningful, color-customized icons without needing design tools or technical expertise.
The app searches across multiple icon providers (Iconify, The Noun Project), automatically translates search terms into the user's language, applies custom colors via an interactive color picker, and exports optimized SVG data URIs that drop directly into CoMapeo configuration files.
mini-svg-data-uri..svg file or copy SVG markup / data URI directly to clipboard.| Search Results | Icon Selection + Color Picker |
![]() | ![]() |
| Mobile Color Picker | |
![]() |
| Technology | Purpose |
|---|---|
| Nuxt 4 | Full-stack Vue framework (SSR + Nitro server) |
| Vue 3 | Reactive UI components (<script setup lang="ts">) |
| Tailwind CSS | Utility-first styling |
| Playwright | End-to-end testing |
| SVGO | SVG optimization |
| Potrace | Raster-to-vector tracing |
| bing-translate-api | Search term translation |
| Husky + lint-staged | Git hooks & pre-commit linting |
CoMapeo Category Set Spreadsheet Plugin is commonly used with CoMapeo Icons. It generates .comapeocat category files from Google Sheets and can use icons produced by this tool for CoMapeo projects.
Clone the repository
git clone https://github.com/digidem/mapeo-icons.git
cd mapeo-icons
Install dependencies
npm install
Set up environment variables
cp .env.example .env
Iconify works out of the box with no credentials. Only add The Noun Project keys if you want it as a fallback provider.
Start the development server
npm run dev
Visit http://localhost:3000 and start searching.
.svg file or copy the SVG markup / data URI to your clipboard.The generated SVG data URIs are ready to paste directly into a CoMapeo configuration.
All variables are optional — the app works with zero configuration using Iconify defaults.
| Variable | Required | Default | Description |
|---|---|---|---|
ICONS_TO_DOWNLOAD | No | 10 | Number of icons to fetch per request |
ICON_PROVIDER_ORDER | No | noun,iconify | Comma-separated provider order |
ICONIFY_API_BASE_URL | No | https://api.iconify.design | Iconify API base URL |
ICONIFY_PREFIXES | No | maki,temaki,material-symbols,mdi,tabler,ph,lucide,heroicons | Comma-separated Iconify icon collections |
NOUN_KEY | No | — | The Noun Project OAuth consumer key |
NOUN_SECRET | No | — | The Noun Project OAuth consumer secret |
CORS | No | — | Set to all or a comma-separated list of allowed origins |
Restart the dev server after changing any of these values.
mapeo-icons/
├── assets/
│ └── main.css # Global Tailwind imports
├── components/
│ ├── ColorPickerMobile.vue # Collapsible mobile color picker
│ ├── Footer.vue # Page footer
│ └── Search.vue # Search form + locale selector
├── libs/
│ └── colorize.js # CSS filter generator (SPSA algorithm)
├── locales/ # i18n translation bundles (7 languages)
├── pages/
│ ├── index.vue # Landing page / search
│ ├── images.vue # Icon grid + color selection
│ └── result.vue # Final SVG output + download/copy
├── public/
│ ├── favicon.ico
│ ├── icon.png
│ ├── logo.webp
│ └── sw.js # Service worker
├── server/
│ ├── api/
│ │ ├── search.get.ts # GET /api/search — icon search endpoint
│ │ └── generate.get.ts # GET /api/generate — SVG generation endpoint
│ └── utils/
│ ├── iconSearch.ts # Multi-provider search logic
│ ├── generateMapeoIcon.ts # SVG colorization + optimization
│ └── translate.ts # Bing Translate wrapper
├── store/
│ └── README.md # State management notes
├── tests/
│ └── e2e/
│ ├── search.spec.ts # Search flow tests
│ ├── color-picker.spec.ts # Color picker tests
│ └── screenshots/ # Test artifacts
├── types/ # TypeScript shims
├── Dockerfile # Production container definition
├── nuxt.config.js # Nuxt configuration
├── tailwind.config.ts # Tailwind theme
└── playwright.config.ts # E2E test configuration
| Command | Description |
|---|---|
npm run dev | Start the Vite-powered Nuxt dev server (localhost:3000) |
npm run build | Compile the production bundle |
npm run preview | Serve the built Nitro output locally |
npm run generate | Pre-render the app as static files |
npm test | Run Playwright E2E suite (headless, port 4173) |
npm run test:headed | Run tests in headed browser mode |
npm run test:ui | Run tests in Playwright UI mode |
npm run lint | Run ESLint + Stylelint + Prettier checks |
npm run lintfix | Autofix lint issues and format all files |
End-to-end tests use Playwright and model complete user journeys:
# Run all tests (boots dev server on port 4173)
npm test
# Watch tests in a browser
npm run test:headed
# Interactive UI mode with time travel debugging
npm run test:ui
Test artifacts (screenshots) are saved in tests/e2e/screenshots/.
The project uses ESLint, Stylelint, and Prettier with Husky pre-commit hooks:
# Check everything
npm run lint
# Auto-fix
npm run lintfix
Commits must follow Conventional Commits format (enforced by commitlint):
feat(search): add locale toggle
fix(images): improve color picker accessibility
chore(deps): update nuxt to v4.4.5
Pre-built images are published to Docker Hub:
docker run -d \
-p 3000:3000 \
-e NOUN_KEY=your_key \
-e NOUN_SECRET=your_secret \
-e ICONS_TO_DOWNLOAD=10 \
communityfirst/mapeo-icons:latest
Images are built for linux/amd64 and linux/arm64. The Docker build pipeline triggers automatically after CI passes on main.
services:
mapeo-icons:
image: communityfirst/mapeo-icons:latest
ports:
- "3000:3000"
environment:
ICONS_TO_DOWNLOAD: 10
ICON_PROVIDER_ORDER: noun,iconify
# NOUN_KEY: your_key
# NOUN_SECRET: your_secret
restart: unless-stopped
The app supports 7 languages with automatic browser detection:
| Code | Language | Flag |
|---|---|---|
en | English | :us: |
pt | Português | :brazil: |
es | Español | :es: |
th | ไทย | :thailand: |
nl | Nederlands | :netherlands: |
fr | Français | :fr: |
id | Bahasa Indonesia | :indonesia: |
Translation files live in locales/*.json. To add a new language, create a new JSON file and register it in nuxt.config.js under i18n.locales.
User searches "cachorro" (pt)
│
▼
┌─────────────────┐ ┌──────────────────┐
│ Bing Translate │────▶│ "dog" (en) │
└─────────────────┘ └────────┬─────────┘
│
┌────────────▼────────────┐
│ Provider Chain │
│ (configurable order) │
├──────────────────────────┤
│ 1. The Noun Project │
│ (scrape → API) │
│ 2. Iconify │
│ (8 collections) │
└────────────┬────────────┘
│
┌────────────▼────────────┐
│ Icon Results (URLs) │
└────────────┬────────────┘
│
┌──────────────────▼──────────────────┐
│ Generate Endpoint │
│ ┌─────────────────────────────────┐ │
│ │ SVG? → Replace fill/stroke attrs │ │
│ │ PNG? → Potrace trace to vector │ │
│ └──────────────┬──────────────────┘ │
│ │ │
│ ┌──────────────▼──────────────────┐ │
│ │ SVGO optimize → data URI │ │
│ └──────────────┬──────────────────┘ │
└─────────────────┼───────────────────┘
│
┌───────────▼───────────┐
│ Colored SVG download │
│ / clipboard copy │
└───────────────────────┘
Contributions are what make the open source community such an amazing place to learn, inspire, and create. Any contributions you make are greatly appreciated.
git checkout -b feature/amazing-feature)git commit -m 'feat(scope): add amazing feature')git push origin feature/amazing-feature)<script setup lang="ts"> for Vue componentsfeat(scope): description)npm run lint and npm test before submitting a PRDistributed under the MIT License. See LICENSE for more information.
Content type
Image
Digest
sha256:4175c5409…
Size
345.3 MB
Last updated
3 months ago
docker pull communityfirst/mapeo-icons