Inside The /ghs Label Builder
One canvas renderer feeds the label preview, PNG export, and print image. Notes on saving drafts, fitting text, and reviewing the source information.
By Kevin O'Connor
Last reviewed
I built the /ghs label builder because making a small chemical label often means fighting a spreadsheet or a template that falls apart when the text gets longer. I wanted to enter reviewed information, see the layout, and get a usable image without maintaining a separate desktop workflow.
The interesting implementation detail is the renderer. The preview, PNG export, and printed image all come from the same canvas drawing code.
Drawing the label once
The builder holds the product information, pictograms, signal word, hazard text, and precautionary text in one state object. The canvas renderer places those fields at the selected size. Export creates another canvas and calls the same renderer at a higher scale; printing uses the resulting image.
That avoids maintaining a screen layout and a print layout that gradually disagree. If I change pictogram spacing or text wrapping, the same change reaches all three outputs. It also makes a clipping bug easier to reproduce because the output paths share the layout logic.
There is still a physical step to check. Browser print settings, printer scaling, label stock, and the container affect the result. Print one at the intended size and look for small text, clipped statements, poor contrast, or a pictogram that becomes hard to recognize. A large preview can hide all of those problems.
The builder also supports hazard-area signs. Optional QR content can carry an identifier or reference, but information needed on the label still has to be readable without scanning it.
Saving a draft
Save JSON writes the builder state to a file; Load JSON brings it back. That's useful when a label needs another review or a small layout change later. Save the file before closing a draft you need to keep.
The share button copies the /ghs URL. It doesn't encode the current label in the link. To give someone an editable draft, send the JSON through whatever channel your organization uses for that information. Approved label records and their SDS references need to be maintained outside the builder; it has no approval workflow.
Getting the content right
The product's identity and formulation determine which source information belongs on the label. A familiar chemical name or a built-in sample isn't enough to establish that the selected hazards apply to a particular container.
For US workplaces, OSHA's Hazard Communication Standard distinguishes shipped-container labeling from workplace labeling. Appendix C sets out the allocation of label elements. Use the requirements that apply to the container, the current SDS for the actual product, and your organization's labeling procedure when reviewing the draft.
I prefer entering verified information directly. The layout should make that information legible without shortening a statement until its meaning changes. When the text doesn't fit, changing the label size is often a better answer than trying to squeeze it into a smaller font.
What happens when AI assistance is used
Manual editing and canvas rendering happen in the browser. The optional AI features send selected product information and label fields to /api/ghs/ai, which calls the configured model provider. That request takes data outside the local editing workflow.
The model can suggest fields, but it may use information for the wrong concentration or formulation, omit a hazard, or produce wording that looks plausible without matching the SDS. Review those suggestions field by field before using them. If a suggestion conflicts with the product documentation, resolve the discrepancy at the source.
The manual path remains useful without the model. Someone who already has reviewed label information should be able to lay it out and print it without waiting for an AI response.
The next layout problems
Long statements at small sizes are where I'd spend more development time. Clearer SDS references and reusable organization presets would help too, especially if the interface made the preset's review status visible.
For a layout bug, the most useful report is the selected size, browser, text that failed to fit, and whether it happened in the preview, PNG, or print. Those details let me recreate the problem with the same renderer instead of trying to infer it from a photograph of the finished label.
Keep reading
AI Systems · 8 min read
ChatGPT, Claude, and Gemini: Subscription Prices Compared
What the free, $20, and higher-priced AI plans actually include, where usage limits apply, and when the Google bundle or a team plan changes the calculation.
AI Security · 4 min read
What AI Agent Assurance Claims Actually Cover
Reading an agent assurance report closely enough to find out which permissions were tested and when the results need revisiting.
Email updates
Get new research by email
In-depth notes on AI security, threat research, and practical defensive work.