How to batch responsive svg wrappers by scripting the jad engine
- Step 1Inventory your SVGs yourself — List the
.svgfiles in your assets folder with your own script (glob,fs.readdir,ls). The wrapper has no inventory or manifest mode — it never scans folders. - Step 2Read each file as text — For each SVG, read the source string. The wrapper accepts SVG text; a malformed file (root not
<svg>) will be rejected, so wrap the call in try/catch. - Step 3Decide the max width per file — Pick a
maxWidthvalue — usually a single project-wide default like100%, or a per-category cap such as480pxfor icons. This is the only option the wrapper takes. - Step 4Call the wrapper once per file — Invoke the transform on each SVG. It strips fixed dimensions, reads the viewBox, and returns one inline-SVG HTML snippet. There is no multi-file call — loop.
- Step 5Write the snippets out — Save each result as
<stem>-responsive.html, or splice the inner HTML into your templates. The output is plain HTML, so it drops into any templating system. - Step 6Re-run on change — Because output is deterministic, wire the loop into a prebuild step. Unchanged SVGs produce byte-identical snippets, so version control stays quiet unless artwork actually changed.
What the batch pattern can and cannot do
Set expectations before you script — these are the real capabilities of the wrapper.
| Capability | Built in? | How to achieve it |
|---|---|---|
| Wrap one SVG | Yes | Single call; reads viewBox, strips width/height |
| Wrap a folder | No | Your own loop over files, one call each |
| Per-file max width | Yes (one value/run) | Pass maxWidth each iteration |
| React/Vue component | No | svg-to-jsx, svg-to-vue-svelte |
| JSON manifest of dimensions | No | Parse viewBox yourself while looping |
| Sprite sheet | No | svg-sprite-builder (multi-input) |
The single option to thread through a batch
The wrapper's complete option surface.
| Option | Type | Default | Notes |
|---|---|---|---|
| maxWidth | CSS length string | 100% | Inserted verbatim into outer div max-width; not validated |
Cookbook
These scripts show the honest batch pattern: enumerate files yourself, then call the single-file wrapper once each. Adapt the call to whichever JAD entry point you use (browser tool, runner engine, or API).
Node loop over a folder
Enumerate SVGs and wrap each. The wrapper is called once per file; there is no batch call.
import { readdir, readFile, writeFile } from "node:fs/promises";
import { wrapResponsive } from "./jad-wrap"; // your binding to the engine
const dir = "src/assets/icons";
for (const name of await readdir(dir)) {
if (!name.endsWith(".svg")) continue;
const svg = await readFile(`${dir}/${name}`, "utf8");
try {
const html = wrapResponsive(svg, { maxWidth: "480px" });
await writeFile(`out/${name.replace(/\.svg$/, "-responsive.html")}`, html);
} catch (e) { console.error("skip", name, String(e)); }
}Guarding against invalid SVGs
A batch will hit broken files. The wrapper throws on non-SVG roots; catch and log so one bad file does not abort the run.
for (const name of files) {
const svg = await readFile(join(dir, name), "utf8");
try {
results.push({ name, html: wrapResponsive(svg, { maxWidth: "100%" }) });
} catch (err) {
skipped.push({ name, reason: String(err) }); // e.g. root is not <svg>
}
}
console.log(`wrapped ${results.length}, skipped ${skipped.length}`);Capturing viewBox while you loop
Since the wrapper does not emit a manifest, compute dimensions yourself in the same pass if you need a report.
const manifest = [];
for (const name of files) {
const svg = await readFile(join(dir, name), "utf8");
const m = svg.match(/viewBox="([\d.]+) ([\d.]+) ([\d.]+) ([\d.]+)"/);
manifest.push({
name,
width: m ? +m[3] : null,
height: m ? +m[4] : null,
ratio: m ? `${m[3]}/${m[4]}` : "1/1 (no viewBox)",
});
}
await writeFile("out/manifest.json", JSON.stringify(manifest, null, 2));Prebuild hook for idempotent regeneration
Wire the loop into package.json. Output is deterministic, so unchanged SVGs produce identical snippets and git stays quiet.
// package.json
{
"scripts": {
"prebuild": "node scripts/wrap-svgs.mjs",
"build": "next build"
}
}
// Re-running wrap-svgs.mjs on the same inputs overwrites with byte-identical files.When you actually want a component, not HTML
The wrapper emits HTML. For framework components, route the same loop to the correct sibling tool.
// Need React? -> svg-to-jsx (emits a .tsx component) // Need Vue/Svelte? -> svg-to-vue-svelte // Need one sprite from many SVGs? -> svg-sprite-builder (accepts multiple) // // The Responsive Wrapper itself only ever returns inline-SVG HTML.
Edge cases and what actually happens
Pointing the tool at a folder
Not supportedThere is no folder or directory mode. The tool processes one SVG per call (files[0]). Enumerate files in your own script and call the wrapper once per file.
Multiple files dropped in the UI
First file onlyIf several SVGs are selected, only the first is processed. Multi-input is reserved for svg-sprite-builder. For batches, loop programmatically.
Expecting a React/Vue component
Not producedThe wrapper outputs plain inline-SVG HTML, not a component. There is no SVGR step. Use svg-to-jsx or svg-to-vue-svelte for components.
Invalid SVG in the batch
ThrowsA file whose root is not <svg> or that fails XML parsing raises an error. In a loop, wrap each call in try/catch so one bad file does not halt the run.
File without a viewBox
Square fallbackEach such file is wrapped as aspect-ratio:1/1. In a batch this silently distorts non-square art. Pre-pass with svg-viewbox-fixer or flag files lacking a viewBox.
Comma or quote variants of viewBox
Square fallbackThe detector matches double-quoted, space-separated, positive numbers only. Normalise exports (svg-pro-minifier) before a batch to avoid silent 1/1 fallbacks.
Expecting a JSON manifest output
Not producedThe wrapper returns only the HTML snippet plus simple metrics. Compute a dimensions manifest yourself by parsing the viewBox in the same loop.
Hitting the tier file-size cap
RejectedFiles over the SVG-family cap for your tier (5 MB Free, 50 MB Pro, 200 MB Pro Media, 2 GB Developer) are rejected. Minify oversized sources first with svg-pro-minifier.
Frequently asked questions
Does the tool have a batch or folder mode?
No. It processes one SVG per run (files[0]). To handle many files, enumerate them in your own script and call the wrapper once per file. The transform is server-safe, so this loops cleanly in the JAD runner engine.
Can it generate React or Vue components?
No. The wrapper emits plain inline-SVG HTML. For a React component use svg-to-jsx; for Vue or Svelte use svg-to-vue-svelte. Those produce framework code; this produces HTML.
Is there an SVGR pipeline inside the wrapper?
No. There is no SVGR or any React transform in this tool. If you saw that claim elsewhere it is incorrect for the Responsive Wrapper — route to svg-to-jsx instead.
How do I wrap a whole assets folder?
Write a short loop (Node fs.readdir, a shell glob, etc.), read each .svg, call the wrapper with your maxWidth, and write each result as <stem>-responsive.html. See the cookbook for a ready script.
Is the output deterministic for prebuild hooks?
Yes. Given the same SVG and maxWidth, the snippet is byte-identical, so re-running a prebuild loop only changes files whose source actually changed.
What options does the batch need to thread through?
Just one: maxWidth, a CSS length string (default 100%). There are no other options, so your config surface stays minimal.
Can I get a manifest of dimensions for all files?
Not from the tool. Parse the viewBox yourself in the same loop — match viewBox="w0 h0 w h" and record w/h. The cookbook shows a manifest example.
How does it behave on a sprite sheet?
A sprite contains many symbols and should not be wrapped as a single aspect box. Use svg-sprite-builder to assemble sprites; the Responsive Wrapper is for one-graphic-per-file assets.
What happens to invalid SVGs in a large batch?
Each invalid file throws. Wrap every call in try/catch and log skips so a single bad file does not abort the whole run.
Does the wrapper hit the network or a server?
No outbound network. On the hosted site it runs in your browser; via the runner it runs in the pure-text engine. Nothing is uploaded.
Will animated SVGs survive the batch?
Yes. The transform only strips width/height and wraps; animation markup is untouched. Output is inline, so CSS/JS/SMIL animations keep working.
What are the per-file size limits in a batch?
SVG-family caps apply per file: 5 MB Free, 50 MB Pro, 200 MB Pro Media, 2 GB Developer, unlimited Enterprise. Batch file counts also scale by tier (1 Free, 20 Pro, 100 Pro Media) when using the UI's multi-select on tools that accept it.
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.