Explain every hard word right where people read it — how to use popup
popup is an that puts an explanation card on the technical terms of any project — web pages, docs and README files. Install it and ask your agent in plain words: it builds the glossary, attaches it to your pages and checks the result in a .
What it makes
A reader who gets stuck on one unknown word loses the whole paragraph. popup puts a small card on that word: hover over it (tap on a phone, Tab with the keyboard) and the card opens. Every explanation lives in one glossary file, so fixing it once fixes every page.
Try it here: hover over a dotted word on this page, such as JSON, or . That is the glossary popup of SONUB, and the cards popup builds look like it.
What one card holds
- The word, how to read it and its field
- The meaning in one bold line
- An explanation in two or three sentences
- In plain words — one everyday comparison
- Examples — one per line, code and what it does
- A source code snippet with a Copy button
- Related terms that switch the card in place, and a "learn more" link to a deeper page of your project
Install
Run this in a terminal in your project folder. Add -g to use it in every project. Start a new session of your agent afterwards so it reads the skill.
npx skills add https://sonub.com -s popup
npx skills add https://sonub.com -s popup -g
The tool popup.py needs only Python 3.8 or later (standard library only). The popup itself runs in any modern browser with no framework and no build step.
How to use it — ask your agent
In Claude Code, type /popup followed by what to focus on. In other agents, say "use the popup skill to …". The narrower the request, the more precisely it does just that part.
Try saying
- “/popup the Getting Started page”
- “/popup token, sampling, temperature”
- “/popup the top menu”
- “/popup make the README easy for beginners”
What the agent does — seven steps
- Find the target It decides which pages, files or sections, and first looks for a glossary or tooltip system the project already has. If there is one, it extends it instead of adding a second popup system.
- Set up once popup.py init copies popup.js and popup.css, writes an empty glossary for the languages you choose and the settings file .popup.json. Then it adds two lines to your layout.
- Audit popup.py audit lists, for each document, the glossary terms it already uses and candidates with no entry: acronyms, camelCase words and words. Words in your own language are not detected, so the reads the text and picks them.
- Choose It picks words a newcomer stops at, words without which the paragraph is lost, and words that repeat across the project. Everyday words and words the text explains right there are left out.
- Write It writes every entry in every language the project ships, with facts it has checked. Entries go into one input file, previewed with popup.py add --dry-run and then merged. Existing entries are never overwritten without --overwrite.
- Attach Plain text inside main and article is wrapped automatically. Inflected forms and sentences are marked with data-term, and a ? button goes next to links, cards and headings. Markdown read on gets GLOSSARY.md and links instead.
- Verify popup.py check validates the glossary, and the agent opens the page in a : hover, leave, click, related terms, Esc, Tab, a narrow screen and another language. Anything it could not check goes into its report.
The popup.py tool — you can run it yourself
popup.py is in the scripts folder of the installed skill (for example .claude/skills/popup/scripts/popup.py) — the boxes below shorten it to popup.py. Paths come from .popup.json at the root of your git repository.
Add it to a web page
There is no build step. Put these two lines in the page or the layout, and popup.js reads the glossary and finds the terms in the text.
<link rel="stylesheet" href="/popup/popup.css">
<script defer src="/popup/popup.js" data-glossary="/popup/glossary.json"></script>
The glossary JSON — every explanation lives here
Pages only point at term ids, and the explanations are written in this one file. Each language needs term, short and long; easy, example, code and reading are optional. An id never changes once it is used.
{
"defaultLocale": "en", "locales": ["en", "ko"],
"categories": { "web": { "en": "Web", "ko": "웹" } },
"terms": {
"api": {
"category": "web", "aliases": ["API", "APIs"], "related": ["endpoint"], "href": "../docs/api.md",
"text": {
"en": { "term": "API", "short": "…", "long": "…", "easy": "…", "example": "`GET /users/42` asks for user 42" },
"ko": { "term": "API", "reading": "에이피아이", "short": "…", "long": "…" }
}
}
}
}
Ways to mark a word
main · article · [data-popup-root]- Automatic — the first use of each term in plain text inside these areas is wrapped
<span data-term="api">APIs</span>- Inflected forms, phrases and sentences that automatic matching should not catch
<button class="popup-info" data-term="api"></button>- A ? button next to links, cards and headings — for phones and keyboards
<a href="/docs/api" data-term="api">- On a link: a preview after resting the mouse for 400 ms, and a click still follows the link
data-popup-scope="shell"- For a word that means something else in one section
PopupGlossary.apply(element)- Wrap new content after a single-page app re-renders (never wraps twice)
It also works with React, Vue and Svelte, MkDocs, Docusaurus and VitePress, server templates and apps — references/integrate.md in the skill shows how for each stack.
On GitHub — README and Markdown
GitHub does not run JavaScript, so Markdown gets links instead of popups. popup.py md writes GLOSSARY.md, and popup.py link connects the first use of each term in every file to it. The link title is the short meaning, so hovering shows it. Code blocks, headings and front matter are left alone, and a | inside a table becomes \| so the table does not break.
Call the [API](../GLOSSARY.md#api "The agreed way one program asks another for something") with an API key.
How readers use it
- Hover opens the card and moving away closes it — moving from the word onto the card keeps it open.
- A click pins the card so you can copy code or follow a link; a second click closes it.
- Related-term chips switch the card in place.
- Tab onto a word opens it, Enter moves into the card, and Esc closes it and puts the focus back on the word.
- On a phone (640 px or narrower) the card is a sheet that slides up from the bottom; near the bottom of a large screen it flips above the word.
- It follows right-to-left languages and dark mode, and matches words the way each script needs: Korean particles, Arabic prefixes, Chinese and Japanese.
Questions
Won’t the page fill up with underlines?
Each term is wrapped only at its first use per page or section, and the skill tells the agent to keep it to three or four underlines per paragraph at most.
My project already has tooltips. What happens?
The agent looks for the existing glossary or tooltip system first and extends it. SONUB, for example, adds entries to its own Laravel glossary in 17 languages instead of adding popup.js.
How does it handle several languages?
All languages sit together in the one glossary JSON. check catches a language that is missing, and the popup shows the language of the page (html lang).
What if an explanation is wrong?
A wrong popup teaches the wrong thing to every reader, so the skill only lets the agent write numbers, versions and behaviour it has checked in the docs or by running the code. To fix one, change the glossary once and every page follows.