DEV Community

Cover image for Implementing a Social Share Feature
Daniel Sasse
Daniel Sasse

Posted on

Implementing a Social Share Feature

A social share feature provides an easy method for users to share content from your web app/page directly to their social media accounts or via email/sms. This can help increase user engagement by facilitating the ability to share specific links, articles, and other content to attract more users.

For most social media outlets, this sharing action can be done by specifying different params in the href attribute of a link. This will allow you create a draft/template of the message that will get shared. Of course, the user will still have the option to edit the message before it is posted.

Contents

Creating Share Links for Social Media

The first step to implementing the social share feature is to obtain the properly formatted urls for the desired social media outlet. Let's examine what this would look like for Twitter.

<a href="https://twitter.com/intent/tweet?url=https://dev.to/dsasse07/beginner-s-guide-to-jest-testing-in-react-1nig&text=Beginner's%20Guide%20to%20Jest%20Testing%20in%20React&via=dannysasse" target="_blank" rel="noreferrer">Share on Twitter</a>
Enter fullscreen mode Exit fullscreen mode
  • The first part of the url (https://twitter.com/intent/tweet) is the Twitter endpoint that will allow us to begin composing a Tweet.
  • Following the endpoint, we see a series of params:
    • url=https://dev.to/dsasse07/beginner-s-guide-to-jest-testing-in-react-1nig
    • Indicates the url that will be highlighted within the Tweet. Twitter will unfurl this link in the tweet using the meta tags at this url.
    • text=Beginner's%20Guide%20to%20Jest%20Testing%20in%20React
    • The text content of the message that we would like to include in the template/draft of the Tweet. Note that this text, like all text in the url, must be URL encoded.
    • via=@dannysasse
    • The twitter handle that we would like to be tagged in the message. This could be an article author, or the twitter account related to your web app.

By providing each of these params into the href of our link, clicking on the link will open a new browser window to Twitter, and will precompose a tweet from whichever Twitter account is logged in on the device. All the user needs to do is press Tweet!

Generated Tweet Preview

The difficult part about creating these social share links however, is that each social media outlet is free to format the sharing url endpoint and params as they choose. For example, Facebook's share format only accepts a single param u=.

https://www.facebook.com/sharer.php?u=https://dev.to/dsasse07/beginner-s-guide-to-jest-testing-in-react-1nig
Enter fullscreen mode Exit fullscreen mode

Fortunately, there are a number of services available that have these formats saved, and can be used to quickly generate the urls for different social media outlets.

Creating Share links for SMS and Email

Creating share links for email and SMS fortunately have a uniform approach:

Email:

The most basic format for an email link uses the mailto: prefix followed by an email address.

<a href="mailto:someone@domain.com" />
Enter fullscreen mode Exit fullscreen mode

When clicked, this link would begin a draft of a new email message to the email address included in the link. Multiple addresses can actually be listed here to include multiple addresses as recipients. This could be helpful for a service like a contact link, however as a social share feature we will not know the email address(es) of the recipients. Fortunately, we can leave the addresses blank, and instead fill in the other optional param fields subject= and body=. For completion sake, cc= and bcc= are also possible param fields, but we will not need them

To create an email link for the same example as above, it would look like this:

<a href="mailto:?subject=Beginner's%20Guide%20to%20Jest%20Testing%20in%20React&body=https://dev.to/dsasse07/beginner-s-guide-to-jest-testing-in-react-1nig%20Check%20out%20this%20new%20article%20on%20Jest%20testing%20in%20React!" target="_blank" rel="noreferrer">Share on Email</a>
Enter fullscreen mode Exit fullscreen mode

When clicked, this link would begin a draft of a new email with the address fields left blank. However the subject line will be pre-filled, and the email body will have the link pre-populated. Please Note, the subject and body must be URL encoded.

Generated Email Template

SMS

SMS links are formatted similar to emails, except use the prefix sms:. Like emails, the "address" following sms: (the phone number) value is optional. We will leave it blank for our share feature since we will not know the recipients phone number. In terms of other param fields, the only option for SMS is body= which will contain the content of the text message. Please note again, the body must be URL encoded.

Example:

<a href="sms:?body=https://dev.to/dsasse07/beginner-s-guide-to-jest-testing-in-react-1nig" target="_blank" rel="noreferrer">Share on SMS</a>
Enter fullscreen mode Exit fullscreen mode

It is worth noting that support for this link format is largely through mobile devices, and you may want to consider hiding the SMS share link when a user is not on a mobile device. Additionally, some systems do not fully support sms links. For example, some versions of iOS do not accept SMS links that contain a body= value.

Displaying the Links

How you utilize these links and implement this feature will vary widely depending on the content that you are trying to share. For example, if you were implementing a share feature for each article on a page, perhaps you want to dynamically adjust the params to be relevant to each article. This might also mean that you use a sub-menu on each article or card.

For example purposes, I created a share action button that would display a series of floating action buttons, one for each link option using React and styled components. The code and working example can be found on CodeSandbox or below the demo gif.

Share Action Buttons

import "./styles.css";
import styled from "styled-components";
import LinkedInIcon from "@material-ui/icons/LinkedIn";
import FacebookIcon from "@material-ui/icons/Facebook";
import TwitterIcon from "@material-ui/icons/Twitter";
import MailOutlineIcon from "@material-ui/icons/MailOutline";
import SmsIcon from "@material-ui/icons/Sms";
import ShareIcon from "@material-ui/icons/Share";
import { useState } from "react";

export const socials = [
  {
    outlet: "LinkedIn",
    href:
      "https://www.linkedin.com/shareArticle?url=https://dev.to/dsasse07/beginner-s-guide-to-jest-testing-in-react-1nig&title=Beginner's%20Guide%20to%20Jest%20Testing%20in%20React",
    background: "#0a66c2",
    color: "white",
    label: "Share on LinkedIn",
    icon: <LinkedInIcon />
  },
  {
    outlet: "Facebook",
    href:
      "https://www.facebook.com/sharer.php?u=https://dev.to/dsasse07/beginner-s-guide-to-jest-testing-in-react-1nig",
    background: "#3b5898",
    color: "white",
    label: "Share on Facebook",
    icon: <FacebookIcon />
  },
  {
    outlet: "Twitter",
    href:
      "https://twitter.com/intent/tweet?url=https://dev.to/dsasse07/beginner-s-guide-to-jest-testing-in-react-1nig&text=Beginner's%20Guide%20to%20Jest%20Testing%20in%20React&via=dannysasse",
    background: "#00aced",
    color: "white",
    label: "Share on Twitter",
    icon: <TwitterIcon />
  },
  {
    outlet: "Email",
    href:
      "mailto:?subject=Beginner's%20Guide%20to%20Jest%20Testing%20in%20React&body=https://dev.to/dsasse07/beginner-s-guide-to-jest-testing-in-react-1nig%20Check%20out%20this%20new%20article%20on%20Jest%20testing%20in%20React!",
    background: "#dd4b39",
    color: "white",
    label: "Share via Email",
    icon: <MailOutlineIcon />
  },
  {
    outlet: "SMS",
    href:
      "sms:?body=https://dev.to/dsasse07/beginner-s-guide-to-jest-testing-in-react-1nig",
    background: "#7bcb20",
    color: "white",
    label: "Share via SMS",
    icon: <SmsIcon />
  }
];

export default function App() {
  const [menuActive, setMenuActive] = useState(false);
  const handleToggleMenu = () => {
    setMenuActive((menuActive) => !menuActive);
  };

  const socialLinks = socials.map((social, index) => {
    return (
      <SocialLink
        as="a"
        href={social.href}
        target="_blank"
        rel="noreferrer"
        aria-label={social.label}
        role="button"
        isActive={menuActive}
        background={social.background}
        color={social.color}
        position={index}
        key={index}
      >
        {social.icon}
      </SocialLink>
    );
  });

  return (
    <Container>
      <h1>Share Feature Implementation</h1>
      <h2>By: Danny Sasse</h2>
      <ShareContainer>
        <ShareButton
          isActive={menuActive}
          aria-label="Share Button"
          aria-expanded={menuActive}
          role="button"
          background="#242424"
          color="white"
          onClick={handleToggleMenu}
        >
          <ShareIcon />
        </ShareButton>
        {socialLinks}
      </ShareContainer>
    </Container>
  );
}

const Container = styled.div`
  display: flex;
  flex-direction: column;
  justify-content: center;
  align-items: center;
  background: mistyrose;
  height: 100vh;
`;

const ShareContainer = styled.div`
  position: relative;
  display: flex;
  align-items: center;
  justify-content: center;
`;
const ShareButton = styled.button`
  display: flex;
  z-index: 1;
  align-items: center;
  justify-content: center;
  background: ${({ background }) => background};
  color: ${({ color }) => color};
  border-radius: 100%;
  outline: none;
  border: 2px solid ${({ background }) => background};
  padding: 8px;
  transform: ${({ isActive }) => (isActive ? "scale(0.8)" : "scale(1.0)")};
  transition: all 0.2s, transform 0.2s 0.2s;
  :hover {
    background: white;
    color: ${({ background }) => background};
  }
`;

const SocialLink = styled(ShareButton)`
  position: absolute;
  z-index: 0;
  transform: none;
  transition: top 0.2s ${({ position }) => `${position * 50}ms`},
    left 0.2s ${({ position }) => `${position * 50}ms`};
  left: ${({ isActive, position }) =>
    isActive ? `${(-1) ** position * Math.ceil(position / 2) * 50}px` : "0"};
  top: ${({ isActive }) => (isActive ? `50px` : "0")};
  box-shadow: ${({ isActive }) => (isActive ? `0 4px 10px 0 gray` : `0`)};
`;

Enter fullscreen mode Exit fullscreen mode

Top comments (2)

Collapse
 
ningxinhui profile image
ningxinhui

The image cannot be displayed when I share it to Twitter facebook

Collapse
 
krishna_3 profile image
Krishna Awate

How to share on Instagram?