Papercut
Guide
Laravel
Reference
Examples
Changelog
GitHub
Guide
Laravel
Reference
Examples
Changelog
GitHub
  • Laravel

    • Laravel
    • Configuration
    • Preview routes

Configuration

To customise Papercut, publish the config file to config/papercut.php:

php artisan vendor:publish --tag=papercut-config

Documents

KeyDefaultDescription
prefix'doc'The Blade tag prefix. Lowercase letters, digits and dashes only. Read when the app boots.
paper'a4'The page size when <x-doc::page> doesn't set one. A paper name, or a width and height like '8.5in 11in'.
margin'20mm'The page margin when <x-doc::page> doesn't set one.
theme[]Document defaults: font_family, font_size (in points), color and line_height.
styles[]Named styles, using the same names as tag attributes.
fonts[]Extra font families. See Fonts.
fallback_fonts[]Families to try, in order, for characters the main font doesn't have.
bookmarkstrueBuilds the PDF's bookmarks panel from headings. false leaves it empty.
image_pathnullThe base directory for relative <x-doc::image src> paths. null means public_path().
cache_dirnullWhere to cache parsed fonts. null uses storage/framework/cache/papercut, and false turns the disk cache off.

Errors

KeyDefaultDescription
overflownull'throw' or 'clip'. null throws in local and testing and clips everywhere else. See Content that doesn't fit.
strictfalseWhen true, an export throws instead of dropping content. Worth turning on in tests. See Strict mode.

HTML

KeyDefaultDescription
html.fonts'none''none', 'embed', 'link' or 'sources'. See Fonts in HTML.
html.font_urlnullA FontUrlResolver class. Required when fonts is 'link'.
html.image_urlnullAn ImageUrlResolver class. null embeds images as data URIs.
html.font_sources[GoogleFonts::class]The font sources to check, in order, when fonts is 'sources'.
html.google_fonts.host'https://fonts.googleapis.com'Use 'https://fonts.bunny.net' for Bunny Fonts.
html.google_fonts.display'swap'font-display: auto, block, swap, fallback or optional.
html.google_fonts.familiesnullnull for every family, or a list of the families to load.
html.local_fonts.mode'embed''embed' or 'link'.
html.local_fonts.familiesnullnull for every registered family, or a list.

Resolvers are set as class names rather than closures, because closures can't survive php artisan config:cache. If you use a closure, you'll get an error naming the key. Each class is built by the container, so you can inject dependencies through the constructor.

namespace App\Pdf;

use Papercut\Image;
use Papercut\Laravel\Html\ImageUrlResolver;

final class CdnImageUrl implements ImageUrlResolver
{
    public function __invoke(Image $image): ?string
    {
        ['kind' => $kind, 'value' => $value] = $image->source();

        return $kind === 'file' ? asset('img/' . basename($value)) : null; // null embeds
    }
}

Markup

KeyDefaultDescription
markup.imagesnullAn ImageResolver class. null treats every <img> as missing.
markup.styles'theme''theme' or 'original'. See Rich text.
markup.blank_paragraphs'drop''drop' or 'keep'.

Markup images

Here's a resolver for a rich text editor that stores uploads on the default disk and serves resized copies from /public/images/{size}/files/uploaded/editor/…:

namespace App\Markup;

use Illuminate\Support\Facades\Storage;
use Papercut\Laravel\Markup\ImageResolver;

final class EditorImages implements ImageResolver
{
    public function __invoke(string $src): ?string
    {
        if (preg_match('#^/public/images/[^/]+/(files/uploaded/editor/.+)$#', $src, $m) !== 1) {
            return null;
        }
        // Reject NUL and any `..` segment: the disk would normalise `editor/../../private/x` to `private/x`.
        if (str_contains($m[1], "\0") || in_array('..', preg_split('#[/\\\\]#', $m[1]) ?: [], true)) {
            return null;
        }
        $disk = Storage::disk();

        return $disk->exists($m[1]) ? $disk->get($m[1]) : null;
    }
}
'markup' => ['images' => \App\Markup\EditorImages::class],

Preview

KeyDefaultDescription
preview.enabledenv('PAPERCUT_PREVIEW', false)Turns on the preview routes.
preview.path'_papercut'The URL prefix for the preview routes.

Mistakes in the html.* and markup.* settings are reported the first time they're used, not when the app boots.

Edit this page on GitHub
Last Updated: 10/27/26, 3:08 PM
Prev
Laravel
Next
Preview routes