Building a Social Feed Widget

The Scrivito Example App features social cards for defining how page content should be displayed on Facebook or Twitter when shared. To support sharing, most, if not all, social platforms offer website owners a means for letting visitors connect to their social media accounts.

In this tutorial, we are going to create a widget that provides you with “share buttons” for a series of social media platforms. Technically, sharing comes down to requesting a URL provided by the respective platform. To this URL, the context – the URL of the page being viewed – is passed. That’s it. All other subsequent actions like signing in, or adding a comment, are handled by the social media platforms themselves. With that said, and for not having to reinvent the wheel, we’re going to make use of react-share, a nice library that gives us the core functionality. Let’s start! All you need beforehand is a locally installed Scrivito Example App.

Installing the react-share module

In a terminal window, switch to your Example App directory and run:

Copy
npm install react-share --save

This adds components for creating share links and rendering the corresponding platforms’ icons to your app.

Creating the SocialFeedWidget

The Example App’s widgets live in the “src/Widgets" subdirectory. In there, each widget has its own directory containing the files defining the widget’s class, its editing configuration, and the component for rendering instances of it. One way to physically create a widget is to duplicate an existing one and rename the directory and the files accordingly. For this tutorial, we used the IconWidget as a template.

The first thing to spend a moment on should be the attributes needed in the widget’s class definition for letting editors select the options they want for an actual widget instance. In this case, only one attribute – for specifying the platforms offered for sharing with – is required. As you can see below, we named it shareButtons and made it a multienum attribute to enable selecting more than one value. For clarity, we’re using only three of the many share buttons react-share has available.

src/Widgets/SocialFeedWidget/SocialFeedWidgetClass
Copy
import * as Scrivito from "scrivito";

const SocialFeedWidget = Scrivito.provideWidgetClass("SocialFeedWidget", {
  attributes: {
    shareButtons: [
      "multienum",
      { values: ["facebook", "twitter", "linkedin"] },
    ],
  },
});

export default SocialFeedWidget;

Next, let’s define in the widget’s editing configuration how this attribute is presented to an editor after adding such a widget to a page and opening its properties.

src/Widgets/SocialFeedWidget/SocialFeedWidgetEditingConfig
Copy
import * as Scrivito from "scrivito";

Scrivito.provideEditingConfig("SocialFeedWidget", {
  title: "Social Feed Buttons",
  attributes: {
    shareButtons: {
      title: "Share buttons",
      description: "Social feed buttons to display",
      values: [
        { value: "facebook", title: "Facebook" },
        { value: "twitter", title: "Twitter" },
        { value: "linkedin", title: "LinkedIn" },
      ],
    },
  },
  properties: ["shareButtons"],
  initialContent: {
    shareButtons: ["facebook"],
  },
});

The above editing configuration will make the properties dialog of any SocialFeedWidget look as shown on the screenshot.

Next, let’s put react-social to work and provide the widget’s component for rendering the selected share buttons.

src/Widgets/SocialFeedWidget/SocialFeedWidgetComponent
Copy
import * as React from "react";
import * as Scrivito from "scrivito";
import {
  FacebookShareButton,
  TwitterShareButton,
  LinkedinShareButton,
  FacebookIcon,
  TwitterIcon,
  LinkedinIcon
  } from 'react-share';

Scrivito.provideComponent("SocialFeedWidget", ({ widget }) => {
  const currentPage = Scrivito.currentPage();
  if (!currentPage) return;

  const currentPageUrl = Scrivito.urlFor(currentPage);

  return widget.get("shareButtons").map(shareButton => {
    switch (shareButton) {
      case "facebook":
        return (
          <FacebookShareButton key={'fb'} className={'btn'} url={currentPageUrl}>
            <FacebookIcon round size={32} />
          </FacebookShareButton>
        );
      case "twitter":
        return (
          <TwitterShareButton key={'tw'} className={'btn'} url={currentPageUrl}>
            <TwitterIcon round size={32} />
          </TwitterShareButton>
        );
      case "linkedin":
        return (
          <LinkedinShareButton key={'li'} className={'btn'} url={currentPageUrl}>
            <LinkedinIcon round size={32} />
          </LinkedinShareButton>
        );
    }
  });
});

The above component first determines the current page and, if it’s available, saves its URL for later use as the url prop value in react-share’s button components. It then iterates the widget’s shareButtons attribute value containing the selected buttons to render the corresponding components.

That was it. You now have a social feed widget you can add to the footer or any individual Example App page.

What’s next?

You might want to have a look at the react-share buttons’ decent set of props for styling them or providing additional pieces of information, e.g. hashtags, to the social media platforms.

If you’d like the widget’s properties dialog to be more appealing (the checkbox labels could be equipped or replaced with icons), consider writing a Scrivito extension for it.