React open mailto E-Mail client onClick with body from textarea
Asked Answered
S

6

32

This sounds like it must have been asked before but I could only find how to do this in react native but I could not find how it's done in normal react for web. Preferably not with an a tag or Link tag that needs to be styled.

Here some code to illustrate what I want to do:

const onClickMailtoHandler = () => {
    //TODO: open default e-mail client e.g. via mailto link with text from (state) variable as body
}

<Button onClick={onClickMailtoHandler}>Send E-Mail</Button>

Here is how to do a mailto link in HTML:

<a href="mailto:[email protected]?body=My custom mail body">E-Mail to Max Mustermann</a>
Speedway answered 7/9, 2020 at 18:23 Comment(4)
It is semantically correct to use an a-tag (<a />). Is there an issue with applying some style to that element (as opposed to the style that is likely applied to the underlying button element)?Levasseur
Are you asking how to open mailTo programmatically (#21462089) or to get the text value from the TextArea?Spearhead
@Spearhead yes I kind of ended up doing that just with window.location. I would approve this as answer if you submit it as such :)Speedway
Links to other answers aren't really answers, but you can certainly show your appreciation by upvoting the linked answer.Levasseur
S
41

I ended up creating a component similar to what @GitGitBoom suggested in the comments.

Here for future Seekers:

import React from "react";
import { Link } from "react-router-dom";

const ButtonMailto = ({ mailto, label }) => {
    return (
        <Link
            to='#'
            onClick={(e) => {
                window.location.href = mailto;
                e.preventDefault();
            }}
        >
            {label}
        </Link>
    );
};

export default ButtonMailto;

Use it like this:

<ButtonMailto label="Write me an E-Mail" mailto="mailto:[email protected]" />
Speedway answered 9/9, 2020 at 20:19 Comment(2)
Using this with react, nextJs & TS, I get an error: Type 'string' is not assignable to type 'Location'. Changing window.location to window.location.href works.Edict
thanks. seems to be how it should be used. changed in code answer also.Speedway
A
19

I've used the following method for opening the default mail client when button is clicked:

<button onClick={() => window.location = 'mailto:[email protected]'}>Contact Me</button>
Accouter answered 5/1, 2022 at 5:2 Comment(2)
Using this with react, nextJs & TS, I get an error: Type 'string' is not assignable to type 'Location'. Changing window.location to window.location.href works.Edict
This is a perfect solution.Gorgias
B
4

Try this

<Link to='javascript:void(0)'
      onClick={() => window.location = 'mailto:[email protected]'}>
  Contact Me
</Link>
<OtherElement onClick={() => window.location = 'mailto:[email protected]'}>
  Contact Me
</OtherElement>
Blanka answered 18/1, 2022 at 9:2 Comment(2)
any idea on typings? Type 'string' is not assignable to type 'Location'Picador
@Picador check this answer https://mcmap.net/q/93878/-set-window-location-with-typescript !Factious
G
3

make any element in jsx click mail write this =

<div onClick={(e) => {window.location.href ='mailto:[email protected]';}}>any thing here </div>

just try it.

Glister answered 11/11, 2022 at 10:38 Comment(0)
P
0

Based on solution of @CodingYourLife and main topic of this problem i made my version of component based on two of my needs. I combined react-router-dom behavior with native behavior of <A> html tag.


Files of Link component

  • index.tsx
  • types.ts
  • styles.ts

index.tsx (below)

import * as React from 'react';

import Typography from '@material-ui/core/Typography';

import { withStyles } from '@material-ui/core';

import { Link as RouterLink } from 'react-router-dom';

import styles from './styles';

import { IProps } from './types';

/**
 * Just a wrapper in order to style properly
 *
 * - router link
 * - native html <a> link
*/
class Link extends React.PureComponent<IProps> {
    render(): JSX.Element {
        const {
            classes,
            href,
            children,
            ...routerLinkProps
        } = this.props;

        if (typeof href === 'string') {
            return (
                <a href={href}>
                    <Typography
                        className={classes.value}
                    >
                        {children}
                    </Typography>
                </a>
            );
        }

        return (
            <RouterLink
                to={'#'} // for <a> link default value because it's required by its lib
                {...routerLinkProps}
            >
                <Typography
                    className={classes.value}
                >
                    {children}
                </Typography>
            </RouterLink>
        );
    }
}

export default withStyles(styles)(Link);

styles.ts (below)

import { Theme, createStyles } from '@material-ui/core';

export default (theme: Theme): ReturnType<typeof createStyles> => createStyles({
    value: {
        display: 'inline-block',
        color: theme.palette.secondary.main,
        fontWeight: 500,

        '&:hover': {
            textDecoration: 'underline',
        },
    },
});

types.ts (below)

import {
    WithStyles,
} from '@material-ui/core';

import { LinkProps } from 'react-router-dom';

import styles from './styles';

export type IProps = WithStyles<typeof styles> & Partial<LinkProps> & {
    href?: string;
};

Used library: material-ui

Patriciate answered 18/5, 2021 at 8:49 Comment(0)
A
0

I achieved this in NextJS 14 by passing the attribute as={Link} to the ListGroup component and the href attribute as href='mailto:[email protected]'

import Link from next/link
import ListGroup from "react-bootstrap/ListGroup";

    <ListGroup.Item as={Link} href='mailto:[email protected]' className={styles.listGroupItem}>
                  [email protected]
                </ListGroup.Item>
Acknowledgment answered 17/2, 2024 at 13:13 Comment(0)

© 2022 - 2025 — McMap. All rights reserved.