jerome
jerome

Reputation: 4977

Gmail strips body out of mailto links

I've been seeing this issue on a website I support, and have confirmed it is the case elsewhere as well.

When using a mailto link for sharing a URL, I see that some clients are fine with displaying the body field from the mailto link in the email, while Gmail strips it out.

I've seen a few related questions here but none suggesting a fix or workaround.

I've also seen some mention that the body field is non-standard, but it seems that it is required that it be honored in the spec.

https://www.rfc-editor.org/rfc/rfc6068#page-7

The creator of a 'mailto' URI cannot expect the resolver of a URI to understand more than the "subject" header field and "body". Clients that resolve 'mailto' URIs into mail messages MUST be able to correctly create [RFC5322]-compliant mail messages using the
"subject" header field and "body".

Is Gmail therefore non-compliant?


To demonstrate the behavior I am seeing, with Gmail as your default email client, paste the following into your browser url bar: mailto:?subject=qux&body=xyzzy

If your experience is consistent with mine, you will not have a body in the Gmail message, and will only have a subject. Upon inspection, you may see that the url bar for the Gmail webapp reads something like the following: https://mail.google.com/mail/u/0/?view=cm&fs=1&tf=1&source=mailto&su=qux, with su representing the subject field from the original mailto url, and sure enough, no field representing body.

Now, changing your default email client (I tried with the Mail macOS application) you will see both subject and body populated.

Has anyone had any luck getting the specified behavior working in Gmail?

Upvotes: 4

Views: 842

Answers (1)

Lanny Heidbreder
Lanny Heidbreder

Reputation: 1403

I've discovered that my answer below will help you get these working when "Gmail" is actually "an external Gmail app using WebCatalog, Epichrome, or similar". But all of this is unnecessary and actually harmful if you set Google Chrome as your OS's default email client and Gmail as Chrome's default email service.

It's possible that the behavior reported here is simply a bug with WebCatalog and nothing else; will come back and update this again if I discover more.


Gmail omits all query string parameters after the first one separated by an unencoded ampersand. So if you put ?subject first, you get only subject; if you put ?body first, you get only the body. I changed this:

<a href="mailto:?body=https%3A%2F%2Fexample.com&amp;subject=Testing">

to this, with the ampersand encoded as %26:

<a href="mailto:?body=https%3A%2F%2Fexample.com%26subject=Testing">

...and it works in Gmail, but Mail.app gets the entire query string as the email body. But as I said, Gmail omits everything after the first unencoded ampersand. So I repeated both body and subject with unencoded ampersands, and this seems to work everywhere:

<a href="mailto:?body=https%3A%2F%2Fexample.com%26subject=Testing&amp;body=https%3A%2F%2Fexample.com&amp;subject=Testing">

Put more clearly, in JavaScript, if bodyText is your URL encoded body text, and subjectText is your URL-encoded subject line, then the format you need for full compatibility with Gmail and others is this:

const emailUrl = `mailto:?body=${bodyText}%26subject=${subjectText}&amp;body=${bodyText}&amp;subject=${subjectText}`;

Here also is a Twig version. This Twig file gets unencoded url and title variables for the body and subject respectively:

{%- macro email_share(body, subject) -%}
  {%- set body -%}body={{ body|replace({'&amp;': '&', '&quot;': '"'})|escape('url') }}{%- endset -%}
  {%- set subject -%}subject={{ subject|replace({'&amp;': '&', '&quot;': '"'})|escape('url') }}{%- endset -%}
  {%- set query_string -%}?{{ body|replace({'%26': '%2526'}) }}%26{{ subject|replace({'%26': '%2526'}) }}&{{ body }}&{{ subject }}{%- endset -%}
  {{- query_string -}}
{%- endmacro -%}

{% import _self as self %}

<a class="share__button" href="mailto:{{ self.email_share(url, title) }}">Share via email</a>

Upvotes: 2

Related Questions