Adding "Add to calendar" buttons for multiple targets (Google, Outlook, iCal) to an email invitation

Last modified on July 24, 2026 • 4 min read • 760 words
It is surprising that an “Add-to-calendar button” functionality is missing from all the large email clients.
Adding "Add to calendar" buttons for multiple targets (Google, Outlook, iCal) to an email invitation
Image by Michael Jeltsch

This is more work than it should be in 2026. These were the first instructions that worked for me: https://www.litmus.com/blog/how-to-create-an-add-to-calendar-link-for-your-emails/  . The instructions essentially use hand-written code (and code generated with Amit Agarwal’s Calendar Links tool ( https://www.labnol.org/apps/calendar.html  ).

However, there must be a Chrome plugin to do all this? Or a java script? The instructions are using a combination of different online tools, which makes the process tedious… Unfortunately, if all what I have read is correct, there is no good free solution (contact me if you know otherwise!). Even worse, there is no way to add an event automatically to Apple’s iCloud calendar short of importing an iCal file (which requires lots of manual clicking).

But both Google and Outlook accept calendar event data directly in the GET query parameters of the request URL (i.e. a simple html link or button that you can click). It is relatively easy to add buttons to an email that will open Google Calendar or Outlook and populate the respective calendar fields. As already mentioned, only Apple’s iCal still does not support this feature, and one workaround is to offer iCal file for download to import into iCal, although this requires you to have this file on some sort of server (Gdrive, OneDrive of DropBox would work as well).

But how can I get easily generate the buttons with the necessary code into an email in seconds when writing the email? My answer is: with Espanso! Espanso ( https://espanso.org/  ) listens to all your keystrokes and triggers certain events when it sees certain combinations, that you can freely define. I have assigned the “\cal” letters to a script that pops up a dialog with fields to enter “event”, “location”, “start date/time” and “end date/time”, and then inserts a button into my email client with the correct data. Again, Apple users have to download the .ical file and import it into iCalendar. Unfortunately, generating the iCal file and upload it to a server is way more work than it should be. You can use Amit Agarwal’s webtool to generate the file ( https://www.labnol.org/apps/calendar.html  ), then upload it to a server or file sharing service of your choice and note down the URL to insert into the Espanso form. Also relativley easy - on Linux or Mac - is to upload the on-the-fly generated iCal file via scp to the server of your choice as done in the Espanso YAML configuration entry below. Note that the scp command uses passwordless authentication, which you need to setup!

  - trigger: "/cal"
    vars:
      - name: form
        type: form
        params:
          layout: |
            Event Title (use %20 for spaces): [[title]]
            Location (use %20 for spaces): [[loc]]
            Date (YYYY-MM-DD): [[date]]
            Start Time (HH:MM): [[start]]
            End Time (HH:MM): [[end]]
      - name: gdate
        type: shell
        params:
          cmd: "echo '{{form.date}}' | tr -d '-'"
      - name: gstart
        type: shell
        params:
          cmd: "echo '{{form.start}}' | tr -d ':'"
      - name: gend
        type: shell
        params:
          cmd: "echo '{{form.end}}' | tr -d ':'"
      - name: ics_filename
        type: shell
        params:
          cmd: |
            FILENAME="event_{{gdate}}_{{gstart}}.ics"
            TITLE_CLEAN=$(echo '{{form.title}}' | sed 's/%20/ /g')
            LOC_CLEAN=$(echo '{{form.loc}}' | sed 's/%20/ /g')
            
            # Generate the iCal file locally
            cat <<EOF > "/tmp/$FILENAME"
            BEGIN:VCALENDAR
            VERSION:2.0
            PRODID:-//mjlab.fi//Espanso//EN
            BEGIN:VEVENT
            SUMMARY:$TITLE_CLEAN
            DTSTART:{{gdate}}T{{gstart}}00
            DTEND:{{gdate}}T{{gend}}00
            LOCATION:$LOC_CLEAN
            END:VEVENT
            END:VCALENDAR
            EOF
            
            # Upload to your server (Uncomment and edit the path/user to match your server)
            scp /tmp/$FILENAME user@mjlab.fi:/var/www/mjlab.fi/iCal/$FILENAME > /dev/null 2>&1
            
            echo "$FILENAME"
    html: |
      <html>
      <body>
      <style>
        .addToCalendar_google { background-color: #bf3f3f; border-radius: 28px; border: 1px solid #8f0e0e; display: inline-block; cursor: pointer; color: #ffffff; font-family: Arial, sans-serif; font-size: 16px; padding: 6px 12px; text-decoration: none; text-shadow: 0px 1px 0px #441515; margin: 5px; }
        .addToCalendar_windows { background-color: #4981c1; border-radius: 28px; border: 1px solid #100f4e; display: inline-block; cursor: pointer; color: #ffffff; font-family: Arial, sans-serif; font-size: 16px; padding: 6px 12px; text-decoration: none; text-shadow: 0px 1px 0px #273066; margin: 5px; }
        .addToCalendar_apple { background-color: #8f8f8f; border-radius: 28px; border: 1px solid #2c302c; display: inline-block; cursor: pointer; color: #ffffff; font-family: Arial, sans-serif; font-size: 16px; padding: 6px 12px; text-decoration: none; text-shadow: 0px 1px 0px #080c07; margin: 5px; }
        .addToCalendar_google img, .addToCalendar_windows img, .addToCalendar_apple img { width: 20px; height: 20px; vertical-align: middle; border: none; }
        .addToCalendar_google span, .addToCalendar_windows span, .addToCalendar_apple span { vertical-align: middle; padding-left: 12px; }
      </style>
      
      <a href="https://calendar.google.com/calendar/render?action=TEMPLATE&text={{form.title}}&dates={{gdate}}T{{gstart}}00/{{gdate}}T{{gend}}00&location={{form.loc}}" class="addToCalendar_google">
        <img src="https://mjlab.fi/iCal/google.png" alt="Google" width="20" height="20" style="margin-right: 6px; vertical-align: middle; border: none;" />
        <span>Add to Google Calendar</span>
      </a>
      <a href="https://outlook.office.com/calendar/0/action/compose?allday=false&subject={{form.title}}&startdt={{form.date}}T{{form.start}}:00&enddt={{form.date}}T{{form.end}}:00&location={{form.loc}}&path=%2Fcalendar%2Faction%2Fcompose&rru=addevent" class="addToCalendar_windows">
        <img src="https://mjlab.fi/iCal/windows.png" alt="Outlook" width="20" height="20" style="margin-right: 6px; vertical-align: middle; border: none;" />
        <span>Add to MS Outlook</span>
      </a>
      <a href="https://mjlab.fi/iCal/{{ics_filename}}" class="addToCalendar_apple">
        <img src="https://mjlab.fi/iCal/apple.png" alt="Apple" width="20" height="20" style="margin-right: 6px; vertical-align: middle; border: none;" />
        <span>Add to Apple (iCal file)</span>
      </a>
      
      </body>
      </html>