27

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:max.mustermann@example.com?body=My custom mail body">E-Mail to Max Mustermann</a>
CodingYourLife
  • 7,172
  • 5
  • 55
  • 69
  • 2
    It is semantically correct to use an a-tag (``). 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*)? – Drew Reese Sep 07 '20 at 18:29
  • 2
    Are you asking how to open mailTo programmatically (https://stackoverflow.com/questions/21461589/javascript-mailto-using-window-open) or to get the text value from the TextArea? – GitGitBoom Sep 07 '20 at 18:38
  • @GitGitBoom yes I kind of ended up doing that just with window.location. I would approve this as answer if you submit it as such :) – CodingYourLife Sep 07 '20 at 22:25
  • Links to other answers aren't really answers, but you can certainly show your appreciation by upvoting the linked answer. – Drew Reese Sep 08 '20 at 15:05

5 Answers5

35

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:no-reply@example.com" />
CodingYourLife
  • 7,172
  • 5
  • 55
  • 69
  • 1
    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. – tsb5555 Mar 06 '22 at 08:57
  • thanks. seems to be how it should be used. changed in code answer also. – CodingYourLife Mar 06 '22 at 12:05
14

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

<button onClick={() => window.location = 'mailto:yourmail@domain.com'}>Contact Me</button>
Code_Elixer
  • 141
  • 1
  • 3
3

Try this

<Link to='javascript:void(0)'
      onClick={() => window.location = 'mailto:yourmail@domain.com'}>
  Contact Me
</Link>
<OtherElement onClick={() => window.location = 'mailto:yourmail@domain.com'}>
  Contact Me
</OtherElement>
GMKHussain
  • 3,342
  • 1
  • 21
  • 19
3

make any element in jsx click mail write this =

<div onClick={(e) => {window.location.href ='mailto:example@email.com';}}>any thing here </div>

just try it.

Ej Mahadi
  • 33
  • 4
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

Tomerikoo
  • 18,379
  • 16
  • 47
  • 61
Kas Elvirov
  • 7,394
  • 4
  • 40
  • 62