Weave 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 Vcard Laravel Package

astrotomic/laravel-vcard

Generate and download vCard (.vcf) files in Laravel with a fluent, expressive builder. Map Eloquent models or plain data to vCard 3.0/4.0 contact cards, customize fields, and serve them as downloadable files or responses—ideal for adding "Save contact" features to any app.

View on GitHub
Deep Wiki
Context7

Getting Started

  • Install with composer require astrotomic/laravel-vcard. The service provider and VCard facade are auto-discovered; there is nothing to register by hand in a standard Laravel app.
  • Check whether the release ships a config file before assuming defaults are fine: run php artisan vendor:publish --tag=vcard-config (or check src/ for a config/ directory). If nothing is published, the package is convention-driven and requires no configuration.
  • Read in this order: the README's usage example (fastest path to a working .vcf), then the facade class and the underlying builder in src/, then the test suite — the tests are the authoritative list of supported fields and method names, which matters for a 0.x package where the fluent API is still moving.
  • First use case: a controller action that returns a downloadable contact card for the logged-in user. Build the card fluently, then return a download response. A minimal shape looks like:
return VCard::make()
    ->name($user->name)
    ->email($user->email)
    ->phone($user->phone)
    ->download("{$user->slug}.vcf");
  • For anything richer than name/email/phone (address, organization, URL, birthday, photo, notes), confirm the exact method signatures in the source before writing code — 0.x releases have renamed and reordered builder methods between minors.

On 0.8.1 specifically: the release is a patch on top of 0.8.0 with no documented behavioural changes. If you are already on 0.8.x, treat it as a drop-in upgrade; if you are starting fresh, pin ^0.8 and start here.

Implementation Patterns

  • Dedicated controller, not inline closures. A single-action VCardController (or an invokable controller with route-model binding) keeps the fluent chain out of routes/web.php and makes the endpoint testable.
  • Presenter/factory per contact type. Put card construction in one place — e.g. App\Support\VCardFactory::forUser($user) or a toVCard() presenter class — rather than repeating the chain in a controller and a queued job. This is where you branch on optional fields (filled($user->phone) ? ->phone(...) : $card) and where you centralise escaping rules.
  • Null-safe chaining. Optional profile fields are the norm. Wrap each optional segment in a conditional or use a small tap()-based helper so a missing address does not emit an empty ADR:;;;; block that some clients render as a blank entry.
  • Download vs. persist vs. string. Three distinct outputs are typically needed: an HTTP download for "Add to contacts" buttons, a written file for later attachment to mail (store on a disk and attach via Storage::path()), and a raw string for tests or for embedding in a signed URL flow. Keep the filename in one constant/config value so Content-Disposition and the stored path never drift.
  • Multiple contacts in one file. vCard files permit concatenated BEGIN:VCARD ... END:VCARD blocks. For an "export my team" feature, generate each card and concatenate with the required CRLF separation rather than zipping N files — most address books import the combined file in one step.
  • Photos. Read the avatar from a disk (Storage::disk('public')->get($path)), and downsample before embedding. Base64 photos are the single biggest driver of file size and client-side import failures.
  • Response headers. Set Content-Type: text/vcard; charset=utf-8 and an explicit attachment filename yourself if you bypass the package's download() helper — mobile Safari and Outlook are picky about the MIME type and will show the raw text instead of offering an import.
  • Testing. Assert BEGIN:VCARD/END:VCARD presence and key fields rather than exact full-string equality where you can; when you do need a snapshot, normalise line endings first. Also assert the Content-Disposition header — a regression there breaks the "add to contacts" flow silently.
  • Public-facing links. For "add me to your contacts" links in email footers, generate a signed or tokenised route so the endpoint cannot be enumerated, and keep the action cheap enough to serve without auth.

Gotchas and Tips

  • CRLF is mandatory. The spec requires \r\n line endings. If you post-process the output (trimming, templating, storing in a DB column), verify you have not collapsed them; some parsers reject LF-only files.
  • Line folding at 75 octets. Long NOTE, ADR, and photo payloads are folded onto continuation lines. This is correct behaviour, but it breaks naive string assertions and any regex you write against the raw output — test field-by-field or unfold before asserting.
  • Escaping commas, semicolons, and newlines. Structured fields (N, ADR, ORG) use ; and , as delimiters. A company name like Acme, Inc. or an address line containing a semicolon must be escaped, or the card will import with fields shifted. This is the most common source of "it looked fine in the dump but Contacts shows garbage" bugs.
  • Non-ASCII names. UTF-8 with an explicit charset parameter works in modern clients, but older Outlook/Exchange stacks prefer vCard 3.0. If your user base is enterprise-mail heavy, generate 3.0 rather than 4.0 and test with an actual import — the differences are not cosmetic.
  • Version pinning. Pre-1.0, minor bumps can carry breaking changes. Pin ^0.8 (or exact) and read the compare link in the release notes before taking 0.9. The 0.8.1 patch carries no documented changes, so no migration work is expected from 0.8.0.
  • Storage disk visibility. Storage::put() returning true says nothing about public accessibility. If the .vcf is meant to be fetched by a client, put it on a disk with the correct visibility or serve it through a controller instead.
  • Silent field omissions. Fluent builders generally accept anything; if a field never appears in the output, it is usually a typo in the method name that was swallowed or an unsupported property for the selected vCard version. Dump the raw string before the response and diff it against the source's supported-field list.
  • Debugging loop. dd($card->toString()) (or whatever the string accessor is in this version) before wiring up the HTTP response. Then validate by actually importing the file into macOS Contacts, Google Contacts, and iOS — a card that opens correctly in a text editor still fails import surprisingly often.
  • Extension points. Bind your own subclass or implementation in a service provider if you need custom fields, and keep a thin application-level wrapper around the facade so a future API rename touches one file rather than every controller.
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.
diephp/sequences
users-au/socialite-provider
twidpay/twid-logger
mrnewport/laravel-plaid
mrnewport/laravel-repo
mrnewport/laravel-docsign
mrnewport/laravel-stow
mrnewport/laravel-flow
mrnewport/laravel-priceable
mrnewport/laravel-nestedterms
fredmeng/laravel-apidoc-generator
itstructure/laravel-multilingual-tools
pdustdar/elasticsearch
markupai/php-sdk
rlacerda83/lumem-microservice-shipment
uni-method/symfony-lib
tacticmedia/scim-server-bundle
neika-ai/symfony-bundle
mattleads/agent-publishing-bundle
glavweb/framework-bundle