
QR Codes for Every Bus Stop, Printed by the Website Itself
Bolted to poles across Corpus Christi, at every stop in CCRTA's system, is a 4-inch vinyl sticker: scan it and your phone opens that exact stop's live departure board. We wrote about the tracker behind those pages and the data pipeline underneath it. This post is about the stickers themselves, because they came from an unusual place. Nobody opened a design tool. The print vendor's proofs (CMYK separations, kiss-cut lines, crop marks, outlined type, imposed on 44-inch sheets) were generated by the website's own codebase, from the same data that runs the live map.
One Shape Model, Three Renderers
The sticker is defined once, as a small abstract shape model: rectangles, circles, text, and paths, with coordinates in printer's points. The QR matrix comes from the open-source qrcode library, and the design renders data modules as dots and the three finder squares as concentric circles, with the CCRTA mark knocked out of the center, per the client's design. Pure black on white, for scan contrast.
That one layout then feeds three renderers. On screen, it serializes to SVG: the site has a public digest page where staff can preview any sticker exactly as it will print. On demand, a server endpoint renders any single stop's sticker as a PDF. And in batch, a script renders the full print run. Same shapes, same code, three outputs, which means the preview a staff member approves and the proof the vendor receives cannot drift apart.
What the Printer Actually Requires
Print vendors have requirements that web developers rarely meet, and each one shaped the PDF renderer (built on pdf-lib):
- CMYK only, never device RGB. Every color in the document resolves to a CMYK separation. Pure black is emitted as 100% K, on the black plate alone, so the fine QR dots are printed by a single plate and cannot misregister; white is zero ink, knocking out to the vinyl.
- The cut line is artwork. The vendor's spec asks for the kiss-cut path as an outline box in a visible color at the final trim size. Each decal carries a 100% magenta square whose outer edge sits exactly on the 4-inch trim (the stroke is inset by half its width to make that true), a color that cannot be confused with the black artwork.
- No fonts, live or embedded. More on that below.
- Imposition. The batch script lays decals onto 44-inch boards, up to 81 per sheet in a 9 by 9 grid with sheet crop marks, sequential by stop code so a human can find a specific sticker in the stack, with files named by the code range they contain and an index manifest alongside.
The Type Is Not Text
The vendor's "convert all fonts to outlines" requirement is easy in Illustrator and awkward in a programmatic PDF. Our answer runs at build time: a script parses Arimo Bold with opentype.js and bakes every printable ASCII glyph into a generated TypeScript module as raw vector paths with their advance widths. The PDF renderer draws labels by scaling and placing those paths. The shipped document contains no font whatsoever, and the font machinery (the .ttf file, opentype.js itself) stays in dev dependencies; none of it ships to the runtime.
The typeface choice has its own footnote: the design called for Helvetica, which is proprietary and cannot be redistributed in a repo. Arimo is metric-compatible with Arial and Helvetica and licensed under the SIL Open Font License, so at sticker scale it is visually equivalent and legally boring.
The Data Is Real, So the Stickers Are Right
The sticker run is generated from the same enriched GTFS stop list that powers the map and search: real stop codes, filtered to physical child stops, sorted numerically. The chunking is shared between the web digest page, the per-chunk PDF endpoint, and the CLI generator, and the chunk size is defined as the board's decal capacity, so the downloadable files and the print imposition stay in lockstep by construction.
Each QR encodes that stop's production URL plus one small, deliberate flourish: ref=qr. That is one of Plausible's native source-tagging parameters, so every scan shows up in our privacy-respecting analytics as Source: qr, with no tracking script gymnastics, and the parameter is kept short because shorter URLs make sparser, more scannable QR codes.
And because the physical world outlives data feeds, the system plans for the sticker that outlives its stop. GTFS deletes retired stops without comment, so the pipeline diffs each day's feed and archives what disappeared; a scanned sticker at a decommissioned stop lands on a "no longer in service" page instead of a 404.
The Same Trick, Different Products
The stickers are not the only print artifact the site produces. Route brochures render as PDFs through a different path: real HTML pages printed by headless Chromium (local Chrome in development, a lambda-compatible Chromium build on Vercel). The split is deliberate. Stickers are pure geometry, so drawing them directly with pdf-lib gives exact control over separations and cut lines. Brochures are typeset documents in the site's fourteen supported languages, and correct text shaping for Arabic, Thai, Devanagari, and CJK scripts is a browser-engine problem, not something to hand-roll. Two renderers, each chosen for what the output actually is.
The Takeaway
A website that already knows every stop, every route, and every schedule is most of the way to being a print production system; what remains is respecting the print trade's actual requirements instead of exporting an RGB PDF and hoping. For an agency that runs on the leanest fare revenue in the country, that mattered: the alternative was a design agency manually laying out thousands of stickers from a spreadsheet, and re-doing the work every time a stop changes. Instead, the artwork is code, the data is live, and reprinting next year's batch is one command.