Agent skill

UX Map

by smnandre in smnandre/symfony-ux-skills

Symfony UX Map for interactive maps with Leaflet or Google Maps in Symfony.

MITAuto-check: notesFrontend & Design

Install UX Map

skills CLI
$ npx skills add smnandre/symfony-ux-skills --skill ux-map -a claude-code

Project install by default; add -g for ~/.claude/skills/.

GitHub CLI
$ gh skill install smnandre/symfony-ux-skills ux-map --agent claude-code

Project scope by default; add --scope user for a personal install. Needs GitHub CLI 2.90.0 or later (public preview).

Manual copy
$ git clone --depth 1 https://github.com/smnandre/symfony-ux-skills.git skills-src && mkdir -p .claude/skills && cp -r skills-src/skills/ux-map .claude/skills/ux-map && rm -rf skills-src

Use ~/.claude/skills/ instead of .claude/skills for a personal install. The folder must contain SKILL.md.

Claude Code skills documentation · loads skills from .claude/skills/

Facts

Skill name
ux-map
GitHub stars
180
Token cost
~3k tokens
SKILL.md length
395 words
Files
4 (incl. references)
Skills in repo
7
Repo updated
First seen
Licence
MIT

At a glance

Symfony UX Map for interactive maps with Leaflet or Google Maps in Symfony.

  • Displaying maps
  • SKILL.md covers Installation, Quick Reference, Building a Map in PHP and Rendering in Twig, plus 6 more sections
  • Calls composer; reaches tile.openstreetmap.org; needs GOOGLE_MAPS_API_KEY
  • Placing markers

What it does

UX Map is an agent skill from smnandre/symfony-ux-skills. Symfony UX Map for interactive maps with Leaflet or Google Maps in Symfony. Covers markers, polygons, polylines, circles, info windows, and LiveComponent integration. Use when displaying maps, placing markers, drawing shapes or routes, handling map events, building store locators, using custom tile layers, or making maps reactive with LiveComponent. Code triggers: <twig:ux:map /, Map(), Point(), Marker(), Polygon(), Polyline(), Circle(), InfoWindow(), MapOptionsInterface, ComponentWithMapTrait…

Its SKILL.md is about 3k tokens, which your agent loads only when the skill is triggered. The skill folder holds 4 other files, including reference files (for example `references/api.md`, `references/gotchas.md` and `references/patterns.md`).

It sits in Frontend & Design, covering Icons and illustration. It works with Symfony, Google Maps Platform, PHP and Google Gemini. The repository describes itself as: Symfony UX skills for Claude, Gemini, Codex, ... Live Component, Twig Component, Turbo, Stimulus. The licence is MIT.

When your agent uses it

  • Displaying maps
  • Placing markers
  • Handling map events
  • Building store locators

Example prompts

  • “how to display a map”
  • “how to add markers”
  • “how to draw a polygon on a map”
  • “/ux-map”

Requirements

  • A credential in GOOGLE_MAPS_API_KEY

What it can do on your machine

Read from SKILL.md and the folder at commit 1e99301. It shows what the files ask for, not the result of running them.

  • Tool permissions

    Pre-approves nothing: there is no allowed-tools line, so your agent's usual permission prompts apply.

    From allowed-tools in the SKILL.md frontmatter.

  • Runs code

    Shell commands in SKILL.md call:

    • composer

    From the folder's file list and the shell code blocks in SKILL.md.

  • Network

    Hosts in commands or code, which the agent is likely to contact:

    • tile.openstreetmap.org

    From URLs in SKILL.md, links to its own repository left out.

  • Credentials

    Names these keys or tokens, usually read from environment variables:

    • GOOGLE_MAPS_API_KEY

    From names ending in _API_KEY, _TOKEN, _SECRET, _KEY or _PASSWORD in SKILL.md.

Context cost

UX Map loads about 3k tokens when it runs, and up to ~8.5k if it reads all its reference files. Until then it costs about 244 tokens; SKILL.md has 395 words of instructions outside code blocks.

Always · name and description, kept in context so the agent knows when to use it
~244
When it runs · the whole SKILL.md, loaded when a task matches
~3k
With references · SKILL.md plus every file in references/, read only if the agent opens them
~8.5k

Estimates: characters ÷ 4, the usual rule of thumb; real counts depend on the model's tokenizer. Scripts and assets cost tokens only if the agent reads them.

Safety

Auto-check: notes

The automated check noted patterns worth knowing about, such as sudo or a known installer.

  • NoteMentions a .env fileSKILL.md:155
    Set in `.env`:

Automated static check — not a guarantee. Review scripts before installing. It scans the text of SKILL.md for risky patterns (piping downloads into a shell, reading credential files, hidden Unicode, destructive commands); files beside SKILL.md are not scanned.

SKILL.md

The full file from smnandre/symfony-ux-skills at commit 1e99301, republished under its MIT licence (© smnandre). 395 words, ~3,048 tokens.

Download SKILL.mdSave it as .claude/skills/ux-map/SKILL.md (or your agent's skills folder). This skill also uses 3 other files; get the full folder from GitHub.
name
ux-map
description
Symfony UX Map for interactive maps with Leaflet or Google Maps in Symfony. Covers markers, polygons, polylines, circles, info windows, and LiveComponent integration. Use when displaying maps, placing markers, drawing shapes or routes, handling map events, building store locators, using custom tile layers, or making maps reactive with LiveComponent. Code triggers: <twig:ux:map />, Map(), Point(), Marker(), Polygon(), Polyline(), Circle(), InfoWindow(), MapOptionsInterface, ComponentWithMapTrait, fitBoundsToMarkers, ux:map:marker:before-create, ux:map:connect, SYMFONY_UX_MAP_DSN. Also trigger when the user asks "how to display a map", "how to add markers", "how to draw a polygon on a map", "how to handle map click events", "how to make a reactive map", "how to use Leaflet in Symfony", "how to use Google Maps in Symfony", "map not showing", "map has zero height". Do NOT trigger for SVG icons (use ux-icons) or general frontend interactivity (use stimulus).
license
MIT
metadata.author
Simon Andre
metadata.email
smn.andre@gmail.com
metadata.url
https://smnandre.dev
metadata.version
1.2.0

UX Map

Interactive maps in Symfony with Leaflet or Google Maps. Build maps in PHP, render them in Twig, and extend them with Stimulus controllers. Supports markers, polygons, polylines, circles, info windows, and LiveComponent integration.

Installation

bash
# Install the base package
composer require symfony/ux-map

# Then install ONE renderer:
composer require symfony/ux-leaflet-map    # Leaflet (free, open source)
# OR
composer require symfony/ux-google-map     # Google Maps (requires API key)

Quick Reference

Map                    PHP object, holds markers/shapes/options
Point                  latitude + longitude
Marker                 pin on the map, optional InfoWindow
Polygon                closed shape (array of Points)
Polyline               open line (array of Points)
Circle                 center Point + radius in meters
InfoWindow             popup attached to a Marker, Polygon, or Circle
ux_map(map, attrs)     Twig function to render a Map
<twig:ux:map />        Twig component (requires ux-twig-component)

Building a Map in PHP

php
use Symfony\UX\Map\Map;
use Symfony\UX\Map\Point;
use Symfony\UX\Map\Marker;
use Symfony\UX\Map\InfoWindow;
use Symfony\UX\Map\Polygon;
use Symfony\UX\Map\Polyline;
use Symfony\UX\Map\Circle;

$map = (new Map())
    ->center(new Point(48.8566, 2.3522))
    ->zoom(12)
    ->minZoom(3)
    ->maxZoom(18);

// Marker with info window
$map->addMarker(new Marker(
    position: new Point(48.8566, 2.3522),
    title: 'Paris',
    infoWindow: new InfoWindow(
        headerContent: '<b>Paris</b>',
        content: 'The capital of France',
    ),
));

// Marker with custom icon (UX Icons integration)
$map->addMarker(new Marker(
    position: new Point(48.8738, 2.2950),
    title: 'Eiffel Tower',
    icon: Icon::ux('mdi:tower-eiffel')->width(32)->height(32),
    extra: ['category' => 'landmark'],
));

// Polygon (closed area)
$map->addPolygon(new Polygon(
    points: [
        new Point(48.8566, 2.3522),
        new Point(48.8606, 2.3376),
        new Point(48.8530, 2.3499),
    ],
    infoWindow: new InfoWindow(content: 'Central Paris area'),
));

// Polyline (open line)
$map->addPolyline(new Polyline(
    points: [
        new Point(48.8566, 2.3522),
        new Point(48.8738, 2.2950),
    ],
));

// Circle (center + radius in meters)
$map->addCircle(new Circle(
    center: new Point(48.8566, 2.3522),
    radius: 500,
    infoWindow: new InfoWindow(content: '500m radius'),
));

// Auto-fit bounds to show all markers
$map->fitBoundsToMarkers();

Rendering in Twig

Twig Function
twig
{# Basic rendering #}
{{ ux_map(map, {style: 'height: 400px; width: 100%;'}) }}

{# With custom attributes and Stimulus controller #}
{{ ux_map(map, {
    'data-controller': 'custom-map',
    style: 'height: 400px;',
    class: 'rounded shadow'
}) }}
Twig Component (HTML Syntax)

Requires symfony/ux-twig-component. Allows inline map definition without PHP:

html
<twig:ux:map
    :center="[48.8566, 2.3522]"
    zoom="12"
    :markers='[
        {"position": [48.8566, 2.3522], "title": "Paris"},
        {"position": [48.8738, 2.2950], "title": "Eiffel Tower",
         "infoWindow": {"content": "324m tall"}}
    ]'
    :fitBoundsToMarkers="true"
    style="height: 400px; width: 100%;"
    class="rounded shadow"
/>

Configuration

yaml
# config/packages/ux_map.yaml
ux_map:
    renderer: '%env(resolve:default::UX_MAP_DSN)%'

    # Google Maps specific
    google_maps:
        default_map_id: null    # Optional: default Map ID for all maps
Renderer DSN

Set in .env:

bash
# Leaflet (free)
UX_MAP_DSN=leaflet://default

# Google Maps (requires API key)
UX_MAP_DSN=google://GOOGLE_MAPS_API_KEY@default

Renderer Options

Leaflet Options
php
use Symfony\UX\Map\Bridge\Leaflet\LeafletOptions;
use Symfony\UX\Map\Bridge\Leaflet\Option\TileLayer;
use Symfony\UX\Map\Bridge\Leaflet\Option\ZoomControlOptions;
use Symfony\UX\Map\Bridge\Leaflet\Option\AttributionControlOptions;
use Symfony\UX\Map\Bridge\Leaflet\Option\ControlPosition;

$leafletOptions = (new LeafletOptions())
    ->tileLayer(new TileLayer(
        url: 'https://tile.openstreetmap.org/{z}/{x}/{y}.png',
        attribution: '&copy; OpenStreetMap contributors',
        options: ['minZoom' => 5, 'maxZoom' => 18],
    ))
    ->zoomControl(true)
    ->zoomControlOptions(new ZoomControlOptions(ControlPosition::TOP_LEFT))
    ->attributionControl(true)
    ->attributionControlOptions(new AttributionControlOptions(ControlPosition::BOTTOM_LEFT));

$map->options($leafletOptions);
Google Maps Options
php
use Symfony\UX\Map\Bridge\Google\GoogleOptions;
use Symfony\UX\Map\Bridge\Google\Option\ControlPosition;
use Symfony\UX\Map\Bridge\Google\Option\GestureHandling;
use Symfony\UX\Map\Bridge\Google\Option\MapTypeControlOptions;
use Symfony\UX\Map\Bridge\Google\Option\MapTypeControlStyle;
use Symfony\UX\Map\Bridge\Google\Option\ZoomControlOptions;
use Symfony\UX\Map\Bridge\Google\Option\StreetViewControlOptions;
use Symfony\UX\Map\Bridge\Google\Option\FullscreenControlOptions;

$googleOptions = (new GoogleOptions())
    ->mapId('YOUR_MAP_ID')
    ->gestureHandling(GestureHandling::GREEDY)
    ->backgroundColor('#f00')
    ->doubleClickZoom(true)
    ->zoomControlOptions(new ZoomControlOptions(
        position: ControlPosition::BLOCK_START_INLINE_END,
    ))
    ->mapTypeControlOptions(new MapTypeControlOptions(
        mapTypeIds: ['roadmap'],
        position: ControlPosition::INLINE_END_BLOCK_START,
        style: MapTypeControlStyle::DROPDOWN_MENU,
    ))
    ->streetViewControlOptions(new StreetViewControlOptions(
        position: ControlPosition::BLOCK_END_INLINE_START,
    ))
    ->fullscreenControlOptions(new FullscreenControlOptions(
        position: ControlPosition::INLINE_START_BLOCK_END,
    ));

$map->options($googleOptions);

To disable controls:

php
$googleOptions = (new GoogleOptions())
    ->mapId('YOUR_MAP_ID')
    ->zoomControl(false)
    ->mapTypeControl(false)
    ->streetViewControl(false)
    ->fullscreenControl(false);

Map Events (Stimulus)

Attach a custom Stimulus controller to interact with the underlying map:

javascript
// assets/controllers/custom-map_controller.js
import { Controller } from '@hotwired/stimulus';

export default class extends Controller {
    connect() {
        this.element.addEventListener('ux:map:connect', this._onConnect.bind(this));
        this.element.addEventListener('ux:map:marker:after-create', this._onMarkerCreated.bind(this));
    }

    _onConnect(event) {
        const { map, markers } = event.detail;
        console.log('Map ready:', map);
    }

    _onMarkerCreated(event) {
        const { marker, definition } = event.detail;
        if (definition.extra?.category === 'landmark') {
            console.log('Landmark marker created');
        }
    }
}
twig
{{ ux_map(map, {'data-controller': 'custom-map', style: 'height: 400px;'}) }}
Available Events
EventDetailDescription
ux:map:connect{map, markers}Map is initialized and ready
ux:map:marker:before-create{definition}Before a marker is added
ux:map:marker:after-create{marker, definition}After a marker is added
ux:map:polygon:before-create{definition}Before a polygon is added
ux:map:polygon:after-create{polygon, definition}After a polygon is added
ux:map:polyline:before-create{definition}Before a polyline is added
ux:map:polyline:after-create{polyline, definition}After a polyline is added
ux:map:circle:before-create{definition}Before a circle is added
ux:map:circle:after-create{circle, definition}After a circle is added
ux:map:info-window:before-create{definition}Before an info window is created
ux:map:info-window:after-create{infoWindow, definition}After an info window is created

LiveComponent Integration

Use ComponentWithMapTrait to make the map reactive:

php
namespace App\Twig\Components;

use Symfony\UX\LiveComponent\Attribute\AsLiveComponent;
use Symfony\UX\LiveComponent\Attribute\LiveProp;
use Symfony\UX\LiveComponent\DefaultActionTrait;
use Symfony\UX\Map\InfoWindow;
use Symfony\UX\Map\Live\ComponentWithMapTrait;
use Symfony\UX\Map\Map;
use Symfony\UX\Map\Marker;
use Symfony\UX\Map\Point;

#[AsLiveComponent]
final class MapSearch
{
    use DefaultActionTrait;
    use ComponentWithMapTrait;

    #[LiveProp(writable: true)]
    public string $query = '';

    protected function instantiateMap(): Map
    {
        $map = (new Map())
            ->center(new Point(48.8566, 2.3522))
            ->zoom(12)
            ->fitBoundsToMarkers();

        foreach ($this->getFilteredLocations() as $location) {
            $map->addMarker(new Marker(
                position: new Point($location->lat, $location->lng),
                title: $location->name,
                infoWindow: new InfoWindow($location->name),
            ));
        }

        return $map;
    }

    private function getFilteredLocations(): array
    {
        // Filter based on $this->query
        return [];
    }
}
twig
{# templates/components/MapSearch.html.twig #}
<div {{ attributes }}>
    <input type="search" data-model="debounce(300)|query" placeholder="Search locations...">
    {{ ux_map(this.map, {style: 'height: 400px;'}) }}
</div>
Show full SKILL.md (206 more words)Show less

Key Principles

Build in PHP, render in Twig. The Map object is your data model. Add markers, polygons, circles in PHP (where you have access to your database/services). Render in Twig with a single function call.

The renderer is swappable. Leaflet and Google Maps are interchangeable. Your PHP code uses the same Map, Marker, Point classes regardless of renderer. Only renderer-specific options differ.

Use extra for custom data. The extra parameter on markers, polygons, and circles lets you attach arbitrary data that is available in JavaScript events.

Install a renderer. The base symfony/ux-map package provides the PHP API, but you must also install symfony/ux-leaflet-map (free) or symfony/ux-google-map (requires API key). Without a renderer, the map will not render.

Point(lat, lng) -- latitude first. This matches Google Maps convention but is the opposite of GeoJSON [lng, lat]. Getting the order wrong puts markers in the wrong place or in the ocean.

fitBoundsToMarkers() is your friend. Instead of manually calculating center/zoom, let the map auto-fit to show all markers. If there are no markers, the map falls back to the center and zoom you set -- always provide both as defaults.

References

© smnandre, MIT. Rendered from Markdown: HTML in the file is shown as text, images as links, and headings moved down two levels. Raw file

Files

SKILL.md and 3 other files (references) in skills/ux-map of smnandre/symfony-ux-skills.

  • SKILL.md
  • references/api.md
  • references/gotchas.md
  • references/patterns.md

Open the folder on GitHubat commit 1e99301

Compare with similar skills

UX Map next to the 5 skills that share the most tags, products or categories with it. Stars are the repository's; “used in” counts other GitHub owners with a copy.

UX Map compared with similar skills
SkillStarsUsed inTokensAuto-checkLicenceRepo updated
UX Map this skillsmnandre/symfony-ux-skills180—~3kAutomated safety check: NotesMIT
Kill AI Slopyetone/kill-ai-slop1.3k—~1.4kAutomated safety check: PassApache-2.0
Unified Design Routerassafkip/kipi-system112—~2.9kAutomated safety check: PassMIT
Imagensanjay3290/ai-skills4307 repos~657Automated safety check: PassApache-2.0
Imagennexu-io/open-design100k—~279Automated safety check: PassApache-2.0
Tailwindcss Developmentanonaddy/anonaddy4.9k10 repos~865Automated safety check: PassMIT

Similar skills

  • Kill AI Slop

    yetone/kill-ai-slop

    Find and remove AI slop — the generic, machine-default visual and copy tics of vibe-coded products — from a web project.

    1.3k GitHub stars~1.4k tokensUpdated 22 days ago
    Frontend & DesignAuto-check passed
  • Unified Design Router

    assafkip/kipi-system

    Routes visual design requests to built-in logo, corporate identity, slide, banner, social photo and icon workflows, backed by style data and AI image generation.

    112 GitHub stars~2.9k tokensUpdated today
    Frontend & DesignAuto-check passed
  • Imagen

    sanjay3290/ai-skills

    Generate images using Google Gemini's image generation capabilities.

    430 GitHub starsUsed in 7 repos~657 tokens
    Media & CreativeAuto-check passed
  • Imagen

    nexu-io/open-design

    Generate images using Google Gemini's image generation API for UI mockups, icons, illustrations, and visual assets.

    100k GitHub stars~279 tokensUpdated today
    Media & CreativeAuto-check passed
  • Tailwindcss Development

    anonaddy/anonaddy

    Always invoke when the user's message includes 'tailwind' in any form.

    4.9k GitHub starsUsed in 10 repos~865 tokens
    Frontend & DesignAuto-check passed
  • MCP Development

    coollabsio/coolify

    A skill your agent uses for Laravel MCP development. An agent skill from coollabsio/coolify.

    63k GitHub starsUsed in 1 repo~949 tokens
    Frontend & DesignAuto-check passed

More from smnandre/symfony-ux-skills

  • Live Component

    smnandre/symfony-ux-skills

    Symfony UX LiveComponent for reactive server-rendered UI -- components that re-render via AJAX on user interaction, zero JavaScript required.

    180 GitHub stars~3.3k tokensUpdated 3 mo ago
    Auto-check passed
  • Stimulus

    smnandre/symfony-ux-skills

    Stimulus JS framework for Symfony UX -- client-side behavior via HTML data attributes, zero server round-trips.

    180 GitHub stars~2.1k tokensUpdated 3 mo ago
    Auto-check passed
  • Turbo

    smnandre/symfony-ux-skills

    Hotwire Turbo for Symfony UX -- SPA-like speed with zero JavaScript.

    180 GitHub stars~2.9k tokensUpdated 3 mo ago
    Auto-check passed
  • Twig Component

    smnandre/symfony-ux-skills

    Symfony UX TwigComponent for reusable UI building blocks -- server-rendered components with PHP classes and Twig templates.

    180 GitHub stars~2.5k tokensUpdated 3 mo ago
    Auto-check passed
  • UX Icons

    smnandre/symfony-ux-skills

    Symfony UX Icons for rendering SVG icons in Twig templates. An agent skill from smnandre/symfony-ux-skills.

    180 GitHub stars~1.9k tokensUpdated 3 mo ago
    Auto-check passed
  • Symfony UX

    smnandre/symfony-ux-skills

    Symfony UX frontend stack -- decision tree and orchestrator for choosing between Stimulus, Turbo, TwigComponent, LiveComponent, UX Icons, and UX Map.

    180 GitHub stars~3.4k tokensUpdated 3 mo ago
    Auto-check passed

Questions about UX Map

What does UX Map do?

Symfony UX Map for interactive maps with Leaflet or Google Maps in Symfony. UX Map is an agent skill from smnandre/symfony-ux-skills. Symfony UX Map for interactive maps with Leaflet or Google Maps in Symfony.

When should I use UX Map?

UX Map fits situations like: displaying maps; placing markers; handling map events; building store locators.

How do I install UX Map in Claude Code?

Run `npx skills add smnandre/symfony-ux-skills --skill ux-map -a claude-code`. Or copy the skill folder (skills/ux-map in smnandre/symfony-ux-skills) into .claude/skills/ux-map in your project. Claude Code loads it when a task matches its description.

How do I install UX Map in Codex?

Run `npx skills add smnandre/symfony-ux-skills --skill ux-map -a codex`. Or copy the skill folder (skills/ux-map in smnandre/symfony-ux-skills) into .agents/skills/ux-map in your project. Codex loads it when a task matches its description.

Can I use UX Map in Cursor, Gemini CLI or GitHub Copilot?

Cursor, Gemini CLI, GitHub Copilot and OpenCode also load SKILL.md folders. With the skills CLI, run `npx skills add smnandre/symfony-ux-skills --skill ux-map -a cursor` (or -a gemini-cli, github-copilot or opencode for the others). To copy it by hand, put the folder in .cursor/skills/ux-map, .gemini/skills/ux-map, .github/skills/ux-map and .opencode/skills/ux-map in your project.

What does UX Map need to run?

Going by SKILL.md and its folder, UX Map needs the command-line tools its instructions call (composer) and credentials named GOOGLE_MAPS_API_KEY. Our summary lists: A credential in GOOGLE_MAPS_API_KEY.

Does UX Map access the network?

SKILL.md names 1 domain. In commands or code: tile.openstreetmap.org; the agent is likely to contact it when it follows the instructions. This is read from the text; nothing was executed.

Is UX Map safe to install?

Our automated static check of SKILL.md found notes only (mentions a .env file), nothing it rates as a warning. It is not a guarantee. Review the folder before installing.

What licence does UX Map use?

UX Map is published under the MIT licence (declared in SKILL.md). It allows redistribution, so the full SKILL.md is shown on this page.

How many tokens does UX Map use?

About 3k tokens (SKILL.md is roughly 12k characters). Agents keep only the skill's name and description in context until a task matches; then they load SKILL.md in full. Its references folder adds about 5.4k tokens, read only when the agent opens those files.

What are the alternatives to UX Map?

Skills that share tags, products or a category with UX Map: Kill AI Slop (yetone/kill-ai-slop, 1.3k stars), Unified Design Router (assafkip/kipi-system, 112 stars), Imagen (sanjay3290/ai-skills, 430 stars) and Imagen (nexu-io/open-design, 100k stars). The comparison table on this page puts their stars, adoption, token cost, safety result and licence side by side.

Who maintains UX Map?

smnandre (a GitHub user) maintains it in smnandre/symfony-ux-skills, which has 180 GitHub stars. The repository holds 7 skills in this directory. The repository was last updated on June 14, 2026.

Source: smnandre/symfony-ux-skills on GitHub. Facts on this page come from the repository at the commit we read; the author's words are quoted as theirs.