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

Calendar Links Laravel Package

spatie/calendar-links

Generate “Add to calendar” links and ICS files for events. Supports Google Calendar, iCal/Apple Calendar, Outlook and more. Define title, start/end, description and location, then get shareable URLs or downloadable .ics content for your app.

View on GitHub
Deep Wiki
Context7

Getting Started

Minimal Setup

  1. Installation:

    composer require spatie/calendar-links
    

    Add to composer.json if using Laravel's autoloader:

    "autoload": {
        "psr-4": {
            "App\\": "app/",
            "Spatie\\": "vendor/spatie/"
        }
    }
    

    Run composer dump-autoload.

  2. First Use Case: Generate a Google Calendar link for an event in a Laravel controller or Blade template:

    use Spatie\CalendarLinks\Link;
    
    $eventLink = Link::create(
        'Team Meeting',
        new \DateTimeImmutable('2023-12-15 10:00:00'),
        new \DateTimeImmutable('2023-12-15 11:00:00')
    )->google();
    
    return response()->json(['link' => $eventLink]);
    

    Or in Blade:

    <a href="{{ $eventLink->google() }}">Add to Google Calendar</a>
    
  3. Key Files to Reference:

    • vendor/spatie/calendar-links/src/Link.php (Core class)
    • vendor/spatie/calendar-links/src/Generators/ (Service-specific generators)
    • vendor/spatie/calendar-links/README.md (Examples and API docs)

Implementation Patterns

Core Workflows

1. Event Creation Patterns

  • Time-bound Events:
    $link = Link::create(
        'Product Launch',
        new \DateTimeImmutable('2023-11-30 09:00:00'),
        new \DateTimeImmutable('2023-11-30 17:00:00')
    )->timezone('America/New_York');
    
  • All-Day Events (use createAllDay):
    $link = Link::createAllDay(
        'Conference Day',
        new \DateTimeImmutable('2023-12-01'),
        1 // Inclusive days (1 = single day)
    );
    
  • Multi-Day All-Day Events:
    $link = Link::createAllDay(
        'Workshop',
        new \DateTimeImmutable('2023-12-05'),
        3 // 3-day event (Dec 5-7)
    );
    

2. Enriching Events

Add metadata before generating links:

$link = Link::create('Webinar', $start, $end)
    ->description('Laravel Performance Tuning')
    ->address('Online: Zoom Link')
    ->customProperty('X-CUSTOM', 'value');

3. Service-Specific Links

Generate links for different calendar providers:

$googleLink   = $link->google();
$outlookLink  = $link->webOutlook();
$officeLink   = $link->webOffice();
$yahooLink    = $link->yahoo();
$icsDataUri   = $link->ics(); // Data URI for download

4. ICS File Generation

  • Inline ICS (Data URI):
    $icsUri = $link->ics(['UID' => 'unique-id-123']);
    
  • File Output (e.g., for email attachments):
    $icsContent = $link->ics([], ['format' => 'file']);
    Storage::put('events/event.ics', $icsContent);
    
  • Custom ICS Options:
    $link->ics([
        'PRODID' => '-//MyApp//Calendar//EN',
        'URL' => 'https://example.com/event',
        'REMINDER' => [
            'DESCRIPTION' => 'Reminder',
            'TIME' => new \DateTimeImmutable('2023-11-29 16:00:00')
        ]
    ]);
    

5. Custom Generators

Extend the package for unsupported services:

use Spatie\CalendarLinks\Generators\Generator;

class CustomGenerator implements Generator
{
    public function __invoke(Link $link): string
    {
        return "https://custom-calendar.com/add?title={$link->title}&start={$link->from->format('Ymd\THis')}";
    }
}

$customLink = $link->formatWith(new CustomGenerator());

Integration Tips

Laravel-Specific Patterns

  1. Blade Directives: Create a Blade directive for reusable calendar links:

    // app/Providers/BladeServiceProvider.php
    Blade::directive('calendar', function ($expression) {
        $link = eval("return {$expression};");
        return "href=\"{$link->google()}\"";
    });
    

    Usage:

    <a @calendar('$eventLink') class="btn">Add to Calendar</a>
    
  2. Event Model Casting: Cast event attributes to Link objects:

    // app/Models/Event.php
    protected $casts = [
        'calendar_link' => Link::class,
    ];
    

    Usage:

    $event = Event::find(1);
    echo $event->calendar_link->google();
    
  3. API Responses: Return calendar links in API responses:

    return response()->json([
        'event' => $event,
        'calendar_links' => [
            'google' => $link->google(),
            'outlook' => $link->webOutlook(),
            'ics' => $link->ics(),
        ],
    ]);
    
  4. Mailable Attachments: Attach ICS files to emails:

    // app/Mail/EventReminder.php
    public function build()
    {
        $ics = $this->event->calendar_link->ics([], ['format' => 'file']);
        return $this->subject('Event Reminder')
            ->attachData($ics, 'event.ics', ['mime' => 'text/calendar']);
    }
    
  5. Queue Jobs: Generate and send calendar links asynchronously:

    // app/Jobs/SendCalendarInvite.php
    public function handle()
    {
        $link = Link::create(...);
        Mail::to($this->email)->send(new EventReminder($link));
    }
    

Performance Considerations

  • Caching Links: Cache generated links if events are static (e.g., using Cache::remember):
    $link = Cache::remember("event_{$event->id}_link", now()->addHours(1), function () use ($event) {
        return Link::create(...)->google();
    });
    
  • Lazy Loading: Defer link generation until needed (e.g., in Blade):
    @if($showCalendarLinks)
        <a href="{{ $event->calendar_link->google() }}">Add to Google</a>
    @endif
    

Testing Patterns

  1. Unit Tests: Test link generation in isolation:
    public function test_google_link_generation()
    {
        $link = Link::create('Test', new \DateTimeImmutable('2023-12-01'), new \DateTimeImmutable('2023-12-01 12:00:00'));
        $this->assertStringContainsString('action=TEMPLATE', $link->google());
    }
    
  2. Feature Tests: Test Blade/HTML output:
    public function test_calendar_link_in_blade()
    {
        $response = $this->get('/events/1');
        $response->assertSee('href="https://calendar.google.com/...');
    }
    

Gotchas and Tips

Pitfalls and Debugging

1. Date/Time Issues

  • All-Day Events: Ensure createAllDay uses inclusive days (e.g., 1 = single day). The package adds +1 day internally for calendar compatibility.
    // Incorrect: Creates a 0-day event (empty)
    Link::createAllDay('Event', $date, 0);
    
    // Correct: Single-day event
    Link::createAllDay('Event', $date, 1);
    
  • Timezones: Explicitly set timezones to avoid UTC assumptions:
    $link->timezone('Europe/Amsterdam');
    
  • Negative Date Ranges: Throw exceptions if $to is before $from:
    try {
        $link = Link::create('Event', $end, $start); // Throws InvalidLink
    } catch (\InvalidArgumentException $e) {
        // Handle error
    }
    

2. ICS Generation Quirks

  • UID Collisions: Always provide a unique `
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.
nexmo/api-specification
capell-app/block-library
axium/identity
cetria/laravel-dummy-models
cetria/reflection-helper
agropredict/sso-auth-bundle
evolvestudio/spam-protection
datacore/hub-sdk
develia/commons
cuci/prototurk-sdk
cuci/prototurk-sdk-symfony
develia/geo-bundle
dreamzy/livewire-charts
touchestate-sdk/php-sdk
ecotone/kafka
22h/doctrine-garbage-collection-bundle
agtp/agtp-php
agtp/mod-php
splash/sonata-admin
splash/metadata