How to rtl icon design and localization guide for svg
- Step 1Audit and bucket every icon — Sort the set into three groups. Mirror: directional arrows, chevrons, reply/forward, undo/redo, progress, sliders, list-with-direction. Keep: logos, clocks, checkmarks, stars, hearts, gears, media-play (debated — many systems keep it). Redesign: icons whose meaning needs cultural adaptation beyond a flip (e.g. a left-aligned text glyph should become right-aligned, not mirrored).
- Step 2Cross-check against a design system — Material Design ships a per-icon RTL flag and flips flagged icons automatically when
dir="rtl". Apple's HIG gives directional guidance per symbol. Use them as a sanity check for your own classifications — especially for ambiguous icons like media controls. - Step 3Flip the 'mirror' bucket deterministically — Run each Mirror-bucket icon through svg-rtl-mirror. It adds the
scale(-1,1) translate(-W,0)group and leaves path data untouched, so re-running on an unchanged source produces an identical file — important for reproducible builds. - Step 4Pre-process icons with text — Any icon containing live
<text>will mirror into reversed letters. Convert those to outlines with svg-font-to-path first, then flip, so the glyphs become shapes that reflect cleanly. - Step 5Decide the delivery mechanism — For inline SVG /
<img>you can skip files entirely and apply[dir='rtl'] .icon { transform: scaleX(-1) }. For sprite sheets, native apps, Flutter, or email where CSS transforms don't reach, ship the baked-rtl.svgfiles this tool produces. - Step 6Name and store the variants — Keep LTR files as the source of truth; store flipped output with the same base name (the tool appends
-rtl). Don't duplicate Keep-bucket icons into the RTL set — reference the single LTR file for those to avoid drift.
The three icon buckets
Every icon should land in exactly one bucket. The tool only ever touches the first.
| Bucket | Examples | Action | Tool involvement |
|---|---|---|---|
| Mirror | back/forward arrows, chevrons, reply, undo/redo, progress, sliders | Flip horizontally | Run svg-rtl-mirror |
| Keep | logos, clocks, checkmarks, stars, hearts, gears, search | Use the LTR file as-is | None — do not flip |
| Redesign | text-align glyphs, language-specific symbols, hand gestures | Author a new RTL-correct icon | None — manual design |
Delivery method vs. context
Choosing between runtime CSS flipping and pre-baked files.
| Context | CSS scaleX(-1) | Baked -rtl.svg file |
|---|---|---|
| Inline SVG in HTML | Works well | Optional |
<img> with known size | Works | Optional |
SVG sprite (<use>) | Awkward / per-symbol | Recommended |
| Native (iOS/Android/Flutter) | Not applicable | Recommended |
| HTML email | Unsupported in many clients | Required |
Cookbook
How the major design systems express RTL intent, and how to mirror that intent in your own library with a deterministic flip.
Material Design's per-icon flag, replicated
Material flips flagged icons automatically when the document is RTL. You can mirror the pattern with a tiny metadata file plus pre-generated variants.
icon-meta.json (your source of truth):
{
"arrow_back": { "rtl": "mirror" },
"language": { "rtl": "keep" },
"format_align_left": { "rtl": "redesign" }
}
Build step:
for each icon where rtl == "mirror":
svg-rtl-mirror → arrow_back-rtl.svg
keep → reference the single LTR file in RTL too
redesign → flagged for a designer; build fails if missingRuntime CSS flip for inline icons
When you embed SVG inline, you often don't need a second file at all — one CSS rule flips the Mirror bucket.
/* Mark mirror-eligible icons with a class at author time */
[dir="rtl"] .icon--mirror { transform: scaleX(-1); }
<button>
<svg class="icon icon--mirror" viewBox="0 0 24 24">…back arrow…</svg>
Back
</button>
In an RTL page the same source SVG renders mirrored.
Use the baked tool output only where this rule can't reach.Why baked files for sprites and native
CSS transforms don't compose cleanly with <use> references or native rendering. Pre-flipped files sidestep the problem.
Sprite approach (baked): icons.svg → <symbol id="arrow-back">…</symbol> icons-rtl.svg → <symbol id="arrow-back">…flipped…</symbol> Build icons-rtl.svg from the LTR symbols: 1. extract each <symbol> as a standalone SVG 2. svg-rtl-mirror the Mirror-bucket ones 3. rebuild with /svg-tools/svg-sprite-builder Reference #arrow-back from whichever sprite matches dir.
Text-bearing icon: outline before flip
An icon with a live label mirrors into unreadable reversed text. Convert to paths first.
Wrong order:
badge-NEW.svg (has <text>NEW</text>)
→ svg-rtl-mirror → "NEW" renders as "WEN" reversed
Right order:
badge-NEW.svg
→ svg-font-to-path → text becomes <path> outlines
→ svg-rtl-mirror → shapes flip, but you usually KEEP
text-bearing badges (redesign bucket)
Use /svg-tools/svg-font-to-path for step one.Don't mirror the logo
The single most visible RTL mistake. The tool will flip a logo if asked — the guardrail is your classification, not the tool.
Classification: logo.svg → bucket: KEEP (brand asset, fixed orientation) Pipeline guard: Maintain an allowlist of mirror-eligible files. Never feed the whole icons/ folder blindly to the flipper — iterate only over the Mirror bucket.
Edge cases and what actually happens
The tool flips anything you give it
By designRTL Mirror performs geometry reflection only — it has no classifier, no auto-detect, and no concept of 'should this be mirrored'. Bucketing icons into mirror/keep/redesign is a design decision you make; feed the tool only the Mirror bucket.
Media play / pause icons
Usually keepWhether a play triangle flips in RTL is debated. Many systems keep media-transport controls unmirrored because they map to a physical timeline, not reading order. Pick one convention, document it, and apply it consistently — the tool won't decide for you.
Text-alignment icons
Redesign, not mirroralign-left should become the default-alignment glyph in RTL (visually right-aligned), which is a swap to a different icon, not a flip of the same one. Mirroring it produces a misleading asset. Put these in the redesign bucket.
Mirroring a logo
AvoidBrand marks have a fixed orientation. A mirrored logo reads as wrong or counterfeit. The tool has no logo guard — keep logos in the Keep bucket and exclude them from any batch flip.
Gradients you wanted re-anchored
By designThe flip reflects the whole paint as one unit and does not recompute linearGradient coordinates. For most icons that's correct. If your design needs the gradient to keep pointing the same physical direction after the flip, edit x1/x2 manually or re-colour with svg-hex-swapper.
Live text in an icon
Renders reversedMirroring <text> produces backwards letters. Convert to outlines with svg-font-to-path first, though most text-bearing badges belong in the redesign bucket anyway.
Non-directional icon flipped by accident
Wrong assetA flipped checkmark or star is subtly off but easy to miss in review. Maintain an explicit allowlist of mirror-eligible files rather than flipping a whole folder, so Keep-bucket icons can never slip in.
Icon lacks a viewBox
Fallback W=24The flip width comes from the viewBox; with none, the tool assumes 24 and the icon may land off-frame on a non-24 grid. Normalise your set with svg-viewbox-fixer before mirroring so every icon has a correct viewBox.
Frequently asked questions
What are the three icon categories for RTL?
Mirror (directional icons that flip), Keep (non-directional icons left as-is), and Redesign (icons whose RTL form is a different glyph, like text-alignment). Every icon should land in exactly one bucket. The flip tool only ever touches the Mirror bucket.
Does the JAD tool decide which icons to mirror?
No. It does pure geometry reflection — wrap in scale(-1,1) translate(-W,0), leave path data alone. There is no auto-classifier or confidence score. Classification is a design decision; the which-icons reference helps you make it.
Should I mirror a clock icon?
No. Clocks run clockwise regardless of reading direction. Same for compasses, musical notes, pie charts and scientific diagrams — they're in the Keep bucket. Mirroring them produces a wrong asset.
What's the difference between mirroring and rotating?
RTL mirroring is a horizontal reflection: scale(-1, 1) about the vertical axis (which is what the tool applies, then translates back into frame). A 180° rotation would also flip vertically — wrong for RTL. Always reflect, never rotate.
How does Material Design handle RTL icons?
Material ships a per-icon RTL flag; flagged icons are flipped automatically when the page is dir="rtl". You can replicate that with a small metadata file plus pre-generated variants from the flip tool — see the cookbook above.
One file with CSS, or separate RTL files?
Both are valid. A single inline file with [dir='rtl'] { transform: scaleX(-1) } is least to maintain. Separate baked files (what the tool outputs) are needed for sprite sheets, native apps, Flutter and email, where CSS transforms don't apply.
Will mirroring break my gradients?
It reflects the gradient along with the shape as one unit and does not re-anchor gradient coordinates — correct for almost every icon. If you specifically need the gradient direction re-pinned after the flip, adjust the gradient attributes yourself.
How do I keep LTR and RTL variants in sync?
Treat LTR as the source of truth and regenerate RTL from it in your build. Because the flip is deterministic (path data untouched), re-running on an unchanged source yields an identical file, so committed variants stay stable until the source actually changes.
Should non-directional icons be duplicated into the RTL set?
No. Reference the single LTR file for Keep-bucket icons in both directions. Duplicating them invites drift — if someone updates the LTR star but not the RTL copy, you get a mismatch. Only the Mirror bucket needs separate files.
What about icons containing text?
Mirroring reverses live <text>. Convert to outlines with svg-font-to-path before flipping — though most text-bearing icons belong in the redesign bucket anyway, since translated labels usually need re-typesetting, not reflection.
Is RTL Mirror free?
It's a Pro-tier tool. Free accounts see an upgrade prompt instead of the uploader. The flip runs in your browser regardless of tier once you have access — nothing is uploaded.
Does the tool re-anchor a gradient that pointed left?
No. It copies linearGradient/radialGradient defs through unchanged and reflects the whole shape (paint included) as one unit — it never edits x1/x2. For most icons that's the right result; if you need the gradient direction re-pinned after the flip, edit the gradient attributes yourself or re-colour with svg-hex-swapper.
Privacy first
Every JAD SVG tool runs entirely in your browser using the DOM API and Canvas. Your SVG files never leave your device — verified by zero outbound network requests during processing.