---
title: "Builder & options — QR for Laravel | Roundly"
description: "The immutable PendingQr builder — error correction, versions, masks, segmentation, styling, the QrOptions form and option precedence."
url: https://roundly-consulting.com/open-source/docs/qr-for-laravel/builder
language: en
---

[All packages](https://roundly-consulting.com/open-source.md)

[QR for Laravel](https://roundly-consulting.com/open-source/docs/qr-for-laravel.md)

# Builder & options

Qr::…() returns an immutable PendingQr: every call returns a modified copy, so a configured builder is safe to reuse. Every option at once:

```php
use RoundlyConsulting\Qr\Enums\{EciMode, ErrorCorrection, FinderStyle, ModuleStyle, Segmentation, Sensitivity};

$svg = Qr::text('ABC-123')
    ->errorCorrection(ErrorCorrection::High)   // or 'H'
    ->versions(2, 10)                          // or ->version(5)
    ->mask(3)                                  // null = automatic
    ->boostErrorCorrection(false)
    ->eci(EciMode::Never)
    ->segmentation(Segmentation::Optimal)      // Optimal | Single | Byte
    ->kanji()
    ->size(null)                               // responsive (no width/height)
    ->margin(4)
    ->foreground('#1a1a1a')
    ->background('transparent')
    ->moduleStyle(ModuleStyle::Rounded, 0.35)
    ->finderStyle(FinderStyle::Rounded, '#0a58ca')
    ->title('Order ABC-123')
    ->description('Opens the order page')
    ->xmlDeclaration()
    ->sensitivity(Sensitivity::Public)
    ->svg();
```

## Method reference

| Group | Methods |
| --- | --- |
| Encoding | errorCorrection(ErrorCorrection\|string), version(int), versions(int, int), mask(?int), boostErrorCorrection(bool = true), eci(EciMode), segmentation(Segmentation), kanji(bool = true) |
| Rendering | size(?int), margin(int), foreground(string), background(string), moduleStyle(ModuleStyle, ?float $radius), finderStyle(FinderStyle, ?string $color), title(?string), description(?string), xmlDeclaration(bool = true) |
| Policy | sensitivity(Sensitivity), withOptions(QrOptions) |
| Terminals | matrix(): QrMatrix, info(): EncodingInfo, fits(): bool (would matrix() succeed? — no symbol built), svg(): Svg, toDataUri(DataUriEncoding), toHtml(), toResponse($request), \_\_toString(), payload(): Payload |

Setters validate immediately — an out-of-range size, margin, mask or radius throws InvalidOptionException, an unknown colour InvalidColorException.

## One-call options form

Pass a QrOptions DTO to Qr::svg() / Qr::matrix() / Qr::info(), or apply one to an existing builder with withOptions():

```php
use RoundlyConsulting\Qr\DataTransferObjects\QrOptions;

$svg = Qr::svg('https://example.com', new QrOptions(size: 200, errorCorrection: ErrorCorrection::Medium));
$matrix = Qr::matrix('hello', new QrOptions(mask: 2));
$info = Qr::info('hello', new QrOptions(errorCorrection: ErrorCorrection::High)); // EncodingInfo
$svg = Qr::text('hi')->withOptions(new QrOptions(foreground: '#333333'))->svg();
```

Every QrOptions field is nullable; null means not set, so the payload or the config decides:

```php
new QrOptions(                        // every field nullable; null = not set (payload / config decide)
                                      // only one of minVersion/maxVersion: the other bound comes from
                                      // the builder, else qr.versions.*, narrowed to the given bound
                                      // (config 5..12 + maxVersion: 3 → 3..3) so it never conflicts
    size: 200, margin: 2, errorCorrection: ErrorCorrection::Quartile, minVersion: 1, maxVersion: 10,
    mask: null, foreground: '#111111', background: 'transparent', moduleStyle: ModuleStyle::Rounded,
    finderStyle: FinderStyle::Rounded, title: 'Menu', description: null, eci: EciMode::Never,
    sensitivity: Sensitivity::Public,
);
```

## Precedence and locks

- Explicit builder calls and withOptions() write the same slots — last write wins.
- Then the payload’s requirements (PayloadRequirements).
- Then the configuration.
- A payload’s maximum version is a hard cap.
- Options a payload fixes (EPC: level M, byte mode, no ECI, no boost; PAY by square: one alphanumeric segment, no ECI; an otpauth 2FA seed — Qr::otpauth(), or text or a URL holding an otpauth URI: sensitivity Secret) throw InvalidOptionException::lockedByPayload() (reason locked\_by\_payload) at the terminal call when overridden with a different value — the same value is a no-op.

## Title and description

The accessible title defaults to the qr::qr.title translation (“QR code”); the description defaults to a per-payload translation (qr::qr.descriptions.\*) that never interpolates a secret, name, IBAN or amount — URL codes mention only the host. Override either with title() / description().

## Enums

| Enum | Cases |
| --- | --- |
| `ErrorCorrection` | Low (L), Medium (M), Quartile (Q), High (H) — recoveryPercent(), stronger(), tryFromInput() |
| `EciMode` | Auto, Always, Never |
| `Segmentation` | Optimal, Single, Byte |
| `ModuleStyle` | Square, Rounded, Dots |
| `FinderStyle` | Square, Rounded |
| `DataUriEncoding` | Percent, Base64 |
| `Sensitivity` | Public, Personal, Secret — isCacheable(), cacheControl() |

Every enum is backed and carries the enums-for-laravel helpers, so each one can feed a select or a validation rule directly.

## Inspecting a code

```php
$matrix = Qr::matrix('HELLO WORLD');            // QrMatrix: version(), mask(), isDark($x, $y), rows()
$info = Qr::text('HELLO WORLD')->info();        // EncodingInfo: segments, data/capacity bits, mask penalties
echo $matrix->toText();                         // debug print in the terminal
```

## Show your open-source love

This package is free and MIT-licensed. If it saves you time, a one-off donation or a Patreon membership keeps it maintained, tested and documented.

[More ways to support, including crypto](https://roundly-consulting.com/support-us.md)

By donating, you agree to our [donation terms](https://roundly-consulting.com/donation-terms.md).

[Support our open source work (opens in a new tab)](https://donate.stripe.com/dRmeVe8FX5PF1Qd9pXcEw00) [Join us on Patreon (opens in a new tab)](https://www.patreon.com/cw/roundly)

## Want this built into your product?

We integrate our packages into custom Laravel and AI builds. Tell us what you're working on and we'll reply within 48 hours.

[Get a quote in 48 hours](https://roundly-consulting.com/contact.md) [Browse all packages](https://roundly-consulting.com/open-source/docs/qr-for-laravel.md)
