Buttons & Icons
This page answers one question: How do I get an icon from the Invoice Ninja UI repo into the docs page I am editing?
At a glance
- Input: TSX icons from
external/invoiceninja-ui/src/components/icons - Tool:
npm run icons:sync - Output: SVG files in
static/assets/images/icons/ - Usage in Markdown/MDX docs:
<img src="/assets/images/icons/<IconName>.svg" ... /> - Usage in React pages (
src/pages/*.tsx):import Icon from "@site/static/assets/images/icons/<IconName>.svg"
If you only need the fast path, go to: How to use it to reach a concrete result.
Which usage mode?
- Use
<img ...>when editing docs content files indocs/(Markdown/MDX). - Use SVG import as React component when editing page components in
src/pages/.
Icon paths
- Source icons from
external/invoiceninja-ui/src/components/icons. - Store publishable SVGs in
static/assets/images/icons/. - Run
npm run icons:syncto normalize TSX icons into SVGs.
Only keep icons that are actually used in docs to avoid asset bloat.
Icon sync workflow
Use this flow when the icon set in the Invoice Ninja UI repository changed.
- Ensure the UI repo is available at
external/invoiceninja-ui. - Run the sync script:
npm run icons:sync
- Review generated changes in
static/assets/images/icons/. - Validate determinism in CI or before commit:
npm run icons:check
icons:check reruns extraction and fails if Git diff changes, which helps catch
out-of-date icon output.
How to use it to reach a concrete result
Goal: show a specific UI icon on a specific docs page.
- Identify the icon component name in the Invoice Ninja UI repo:
external/invoiceninja-ui/src/components/icons
Example:ArrowRight.tsx-> target file name will beArrowRight.svg. - Generate/update docs icons:
npm run icons:sync
- Confirm the expected output file exists:
static/assets/images/icons/ArrowRight.svg - Use it in your docs page:
<img src="/assets/images/icons/ArrowRight.svg" alt="" aria-hidden="true" />
Or, if you are inside a React page component (src/pages/*.tsx):
import ArrowRightIcon from "@site/static/assets/images/icons/ArrowRight.svg";
<span aria-hidden="true">
<ArrowRightIcon />
</span>
- Reference that image in your CTA/button snippet and run the site locally
(
npm start) to verify it renders.
Expected result:
- The icon is available under
/assets/images/icons/<Name>.svg. - The icon renders either via
<img ...>(docs content) or via SVG component import (React page).
Quick command map by goal
- Update generated icon set from default Invoice Ninja source:
npm run icons:sync - Verify generated icon output is up to date (CI/pre-commit):
npm run icons:check - Use a different icon source directory:
node scripts/extract-icons.js --src /absolute/path/to/icons
Custom source directory
If your icons are not under the default Invoice Ninja checkout path, use one of these overrides:
node scripts/extract-icons.js --src /absolute/path/to/icons
ICON_SRC=/absolute/path/to/icons node scripts/extract-icons.js
What the script does
- Reads TSX icon components.
- Strips JSX-only syntax and normalizes SVG attributes.
- Forces a deterministic root SVG shape (
width/height,viewBox, colors). - Writes output to
static/assets/images/icons/. - Removes stale generated SVGs that no longer exist in source.
Troubleshooting
ICON_SRC not found ...The configured source path does not exist. Ensureexternal/invoiceninja-uiis present or pass--src.- Expected icon SVG not generated
Check script output for
skipping ...notices (for example styled wrappers or unsupported JSX patterns). - Icon file exists but does not render Verify exact filename/case in the image path and restart local dev server.
- I need brand logos (Discord/YouTube/Slack) from UI stack
The Invoice Ninja UI icon set contains generic product icons, not full brand-logo packs. Use the closest UI icon (for example
Users,MediaPlay,Message) for visual consistency.
Minimal CTA buttons
<a href="/docs/self-host/self-host-installation" class="card-btn card-btn-primary">
Primary CTA
</a>
<a href="/docs/user-guide" class="card-btn card-btn-outline">
Secondary CTA
</a>
Buttons with icon
<a class="card-btn card-btn-outline" href="https://www.youtube.com/watch?v=xo6a3KtLC2g" target="_blank" rel="noopener noreferrer">
<img src="/assets/images/icons/MediaPlay.svg" alt="" aria-hidden="true" />
Watch demo
</a>
Primary buttons invert icon color automatically.
Card with CTA stack
<div class="card-panel">
<p><strong>Secure & fast maintenance</strong></p>
<h3>INmanage CLI installer</h3>
<p>Provisioning, upgrades, backups, and alerts in one flow.</p>
<div class="card-cta">
<a class="card-btn card-btn-primary" href="https://github.com/DrDBanner/inmanage" target="_blank" rel="noopener noreferrer">
Open CLI
<img src="/assets/images/icons/ArrowRight.svg" alt="" aria-hidden="true" />
</a>
</div>
</div>
Best practices
- Use
card-btnfor consistency. - For off-site links always include
target="_blank" rel="noopener noreferrer". - Keep CTA labels action-oriented and short.