Weave Code
Code Weaver
Helps Laravel developers discover, compare, and choose open-source packages. See popularity, security, maintainers, and scores at a glance to make better decisions.
Feedback
Share your thoughts, report bugs, or suggest improvements.
Subject
Message

Laravel Sign Pad Laravel Package

creagia/laravel-sign-pad

Laravel package for capturing handwritten signatures via a sign pad, storing them with Eloquent models, and optionally generating certified signed PDFs. Includes install command, configurable storage/redirects, and publishable JS assets for a full signing flow.

View on GitHub
Deep Wiki
Context7

Getting Started

Minimal Setup

  1. Install the package:

    composer require creagia/laravel-sign-pad
    php artisan sign-pad:install
    

    This publishes the config, migrations, and assets to public/vendor/sign-pad/.

  2. Configure your model: Add the RequiresSignature trait and implement CanBeSigned:

    use Creagia\LaravelSignPad\Concerns\RequiresSignature;
    use Creagia\LaravelSignPad\Contracts\CanBeSigned;
    
    class Contract extends Model implements CanBeSigned
    {
        use RequiresSignature;
    }
    
  3. First use case: Render the signature pad in a Blade view:

    @if (!$contract->hasBeenSigned())
        <form action="{{ $contract->getSignatureRoute() }}" method="POST">
            @csrf
            <x-creagia-signature-pad />
        </form>
        <script src="{{ asset('vendor/sign-pad/sign-pad.min.js') }}"></script>
    @endif
    

Key Configuration

  • Disk storage: Modify config/sign-pad.php to specify signature_disk and document_disk.
  • Redirect route: Set redirect_route_name to control post-signature navigation.

Implementation Patterns

Workflows

  1. Signature Collection:

    • Use the getSignatureRoute() method to generate the form endpoint.
    • The package handles validation (e.g., disabled-without-signature attribute) and stores signatures in the signatures table.
  2. PDF Generation:

    • Implement ShouldGenerateSignatureDocument and define getSignatureDocumentTemplate():
      public function getSignatureDocumentTemplate(): SignatureDocumentTemplate
      {
          return new SignatureDocumentTemplate(
              signaturePositions: [
                  new SignaturePosition(page: 1, x: 20, y: 25),
              ],
              template: new BladeDocumentTemplate('pdf.contract_template'),
          );
      }
      
    • The package merges the signature image into the PDF template (Blade or PDF) during submission.
  3. Certified PDFs:

    • Enable certify_documents: true in config/sign-pad.php.
    • Place a TCPDF certificate (e.g., tcpdf.crt) in storage/app/certificates/.
    • Customize certificate metadata in certificate_info (e.g., issuer, subject).

Integration Tips

  • Dynamic Templates: Pass model data to Blade templates via @inject or view composers.
  • Multi-Signature Documents: Define multiple SignaturePosition objects for multi-page PDFs.
  • API Endpoints: Use the Signature model to fetch signed documents:
    $contract->signature->getSignedDocumentAbsolutePath();
    
  • Queue Jobs: Offload PDF generation to a queue (e.g., SignatureDocumentGeneratorJob) for large files.

Common Use Cases

Use Case Implementation Pattern
Contract signing CanBeSigned + Blade template
Invoice approvals ShouldGenerateSignatureDocument + PDF merge
HR onboarding forms Custom SignaturePosition for multi-signature
Audit trails Log signed_at timestamp in model

Gotchas and Tips

Pitfalls

  1. Double Submissions:

    • Ensure your form includes @csrf and avoid duplicate form submissions (fixed in v2.0.1).
    • Use disabled-without-signature to prevent empty submissions.
  2. Signature Storage:

    • Default paths (storage/app/signatures/) may fill up. Configure signature_disk (e.g., public) for web-accessible storage.
    • Tip: Use symbolic links to move files to cloud storage (e.g., S3) post-generation.
  3. PDF Generation Failures:

    • Blade Templates: Ensure the template exists and the model is passed correctly.
    • PDF Templates: Verify the input file path (e.g., storage_path('pdf/template.pdf')).
    • Debug: Check storage/logs/laravel.log for TCPDF errors (e.g., missing fonts or certificates).
  4. Certificate Issues:

    • TCPDF requires a valid certificate. Use the demo cert or generate your own:
      openssl req -x509 -nodes -days 365000 -newkey rsa:1024 -keyout certificate.crt -out certificate.crt
      
    • Gotcha: Certificates expire. Monitor certificate_info['validity'].
  5. Component Customization:

    • Tailwind classes (e.g., pad-classes="rounded-xl") are applied to the canvas. Test responsiveness.
    • Button Text: Use clear-name and submit-name for localization (e.g., submit-name="{{ __('Sign') }}").

Debugging

  • Signature Not Saved:

    • Check signatures table for records. Verify the model_type and model_id match your Eloquent model.
    • Ensure the model implements CanBeSigned.
  • PDF Not Generated:

    • Validate getSignatureDocumentTemplate() returns a valid SignatureDocumentTemplate.
    • Test with a minimal Blade template:
      @extends('pdf.base')
      <div>@include('signature-pad::signature', ['model' => $model])</div>
      
  • JavaScript Errors:

    • Clear browser cache after publishing assets (php artisan vendor:publish --tag=sign-pad-assets).
    • Check console for sign-pad.min.js 404 errors (verify public/vendor/sign-pad/ exists).

Extension Points

  1. Custom Storage: Override the Signature model’s getSignaturePath() or getDocumentPath() methods for custom paths.

  2. Signature Validation: Extend the Signature model to add rules (e.g., minimum signature length):

    public function validateSignature($signatureData)
    {
        return parent::validateSignature($signatureData)
            ->after(function ($validator) {
                $validator->requireMinSignatureLength(100); // Custom rule
            });
    }
    
  3. Webhook Triggers: Dispatch events after signature submission:

    // In your model's trait or controller
    event(new SignatureSubmitted($model, $signature));
    
  4. Multi-Tenant Support: Scope the signatures table by tenant ID in the Signature model’s boot() method:

    protected static function boot()
    {
        parent::boot();
        static::addGlobalScope('tenant', function (Builder $builder) {
            $builder->where('tenant_id', auth()->user()->tenant_id);
        });
    }
    

Performance

  • Large PDFs: Use queues (SignatureDocumentGeneratorJob) to avoid timeouts.
  • Asset Optimization: Minify sign-pad.min.js or use Laravel Mix to bundle it with your app’s JS.

Security

  • CSRF: Always include @csrf in forms.
  • Signed Document Access: Restrict access to getSignedDocumentPath() via middleware (e.g., signed-documents policy).
  • Certificate Security: Store tcpdf.crt outside the web root and restrict permissions (chmod 600).
Weaver

How can I help you explore Laravel packages today?

Conversation history is not saved when not logged in.
Prompt
Add packages to context
No packages found.
hexters/coinpayment
rjcodes/rjcms
act-training/laravel-permissions-manager
alimarchal/laravel-chart-of-accounts
babenkoivan/elastic-scout-driver
mkwebdesign/filament-watchdog-v5
renatomarinho/laravel-page-speed
zedmagdy/filament-business-hours
renatovdemoura/blade-elements-ui
devgeek/beacon-admin
benjamin-rqt/data-watcher-bundle
atriumphp/atrium
sandermuller/package-boost-laravel
sandermuller/boost-skills
redaxo/core
yusufgenc/filament-api-forge
l3aro/rating-star-for-filament
leek/filament-subtenant-scope
anil/file-picker
broqit/fields-ai