jolicode/jolitypo
JoliTypo is a PHP typography fixer that cleans up HTML fragments: smart quotes, dashes, ellipses, non-breaking spaces, and French typography rules. It offers customizable fixers and works well in Laravel or any PHP project.
Architecture fit. Jolitypo is a framework-agnostic, single-purpose PHP text transformer with no Laravel coupling, no service container assumptions, and no database or queue dependencies. That makes it a clean fit as an edge-of-pipeline concern rather than a core domain dependency: it belongs in the presentation/serialization layer (render-time), not in the persistence layer. The natural seam is a thin application service (TypographyFormatter) behind an interface, so the vendor class never leaks into controllers, Blade templates, or domain models. This keeps the blast radius small if the package is abandoned or replaced.
Integration feasibility. Low engineering effort: composer require, a config file, a service provider binding, and a Blade directive or formatter call. The hard part is not wiring — it is deciding where in the content lifecycle to apply it and proving it does not corrupt markup. HTML-safe processing is the package's core promise and also its primary technical risk; any HTML-aware string rewriter can mangle attributes, inline scripts, JSON-LD, <pre>/<code> blocks, or malformed markup. Verify behavior against the actual content shapes in our system (CMS rich text, Markdown-rendered HTML, email templates, generated PDFs) before committing.
Technical risk.
contenteditable fragments, attributes containing quotes/URLs, and embedded JSON. Must be tested, not assumed.Key questions.
<script>, <style>, <pre>, <code>, and comments?mbstring, intl), and do they match every environment we deploy to?Stack fit. Composer-installable, PSR-compatible, no framework assumptions — compatible with any Laravel version whose PHP constraint the package satisfies. Fit is high for Laravel because the framework gives us the three things the package lacks: configuration management, locale resolution, and a place to put the wrapper. Recommended shape:
config/typography.php — enabled flag, per-surface allowlist, locale map, excluded tags.App\Support\Typography\TypographyFormatter — interface plus adapter wrapping the vendor API; only this class imports vendor namespaces.TypographyServiceProvider — binds the interface, publishes config.@typography) for template-level opt-in, deliberately not a global middleware.Migration path. There is no data migration if we adopt render-time transformation; that is the recommended starting posture. If write-time normalization is later justified (e.g., for search consistency), treat it as a separate project: dry-run batch job, diff report per content type, editorial sign-off, backfill in cohorts, and a reversible flag. Never combine adoption of the library with a data rewrite in the same release.
Compatibility. Confirm the package's PHP constraint against the lowest PHP version in production, and confirm intl/mbstring are present in CI, staging, and all runtime images (including queue workers and PDF generators). Pin an exact version in composer.json; do not use a floating constraint for a rendering-affecting dependency.
Sequencing.
Maintenance. Low code footprint, but ownership is real: someone must track upstream releases, re-run golden tests on upgrade, and hold a fork-or-replace contingency. Budget a recurring half-day per quarter plus upgrade testing. Because only the adapter class imports the vendor namespace, replacement cost is bounded to one file and one test suite.
Support. No vendor SLA; support is internal. Document the wrapper, the locale map, and the exclusion rules in the runbook. Editorial stakeholders — not just engineers — need to own the typographic rules per locale, since "correct" French spacing is a content policy decision, not a code decision.
Scaling. Transformation is CPU-bound per request. For page rendering, measure p95 latency impact; if material, cache transformed output keyed by hash(content) + locale + library version. Batch surfaces (bulk exports, newsletter sends, PDF backfills) should run the transform in queue workers with chunking rather than in the request path. Watch memory on large HTML documents if the library builds a full parse tree.
Failure modes to instrument and gate.
<script> contents.Ramp-up. Engineering ramp is a day: the API is simple and the wrapper is thin. QA and editorial ramp is the larger cost — roughly a week to build locale-specific acceptance criteria and review fixtures for French, English, and any other launch locale, plus a font audit for document generation. Plan for a soft launch behind a flag with a per-surface kill switch, and define success as: no structural HTML diffs, no rendering regressions in visual QA, and a measurable improvement in editorial review comments about typography.
How can I help you explore Laravel packages today?