Introduction

The react-share is a plugin written in React.js to initialize the sharing social media icon component in React forms.
Open a command prompt. Create a directory for the SPFx solution.
md spfx-ReactSocialShare
Navigate to the above-created directory.
cd spfx-ReactSocialShare
Run the Yeoman SharePoint Generator to create the solution.
yo @microsoft/sharepoint
Solution Name
Hit Enter to have the default name (spfx-ReactSocialShare this case) or type in any other name for your solution.
Selected choice - Hit Enter
Target for the component
Here, we can select the target environment where we are planning to deploy the client web part; i.e., SharePoint Online or SharePoint OnPremise (SharePoint 2016 onwards).
Selected choice - SharePoint Online only (latest).
Place of files
We may choose to use the same folder or create a subfolder for our solution.
Selected choice - same folder.
Deployment option
Selecting Y will allow the app to be deployed instantly to all sites and be accessible everywhere.
Selected choice - N (install on each site explicitly).
Permissions to access web APIs
Choose if the components in the solution require permission to access web APIs that are unique and not shared with other components in the tenant.
Selected choice - N (solution contains unique permissions)
Type of client-side component to create
We can choose to create a client-side web part or an extension. Choose the web part option.
Selected choice - WebPart
Web part name
Hit Enter to select the default name or type in any other name.
Selected choice - SpfxReactShare
Web part description
Hit Enter to select the default description or type in any other value.
Framework to use
Select any JavaScript framework to develop the component. Available choices are - No JavaScript Framework, React, and Knockout.
Selected choice - React
The Yeoman generator will perform a scaffolding process to generate the solution. The scaffolding process will take a significant amount of time.
Once the scaffolding process is completed, lock down the version of project dependencies by running the below command,
npm shrinkwrap
In the command prompt, type the below command to open the solution in the code editor of your choice.
NPM Packages used,
  1. npm i react-share
  2. npm i @types/react-share
Necessary imports,
  1. import {
  2. FacebookShareCount,
  3. PinterestShareCount,
  4. VKShareCount,
  5. OKShareCount,
  6. RedditShareCount,
  7. TumblrShareCount,
  8. FacebookShareButton,
  9. FacebookMessengerShareButton,
  10. FacebookMessengerIcon,
  11. LinkedinShareButton,
  12. TwitterShareButton,
  13. PinterestShareButton,
  14. VKShareButton,
  15. OKShareButton,
  16. TelegramShareButton,
  17. WhatsappShareButton,
  18. RedditShareButton,
  19. EmailShareButton,
  20. TumblrShareButton,
  21. LivejournalShareButton,
  22. MailruShareButton,
  23. ViberShareButton,
  24. WorkplaceShareButton,
  25. LineShareButton,
  26. WeiboShareButton,
  27. PocketShareButton,
  28. InstapaperShareButton,
  29. FacebookIcon,
  30. TwitterIcon,
  31. LinkedinIcon,
  32. PinterestIcon,
  33. VKIcon,
  34. OKIcon,
  35. TelegramIcon,
  36. WhatsappIcon,
  37. RedditIcon,
  38. TumblrIcon,
  39. MailruIcon,
  40. EmailIcon,
  41. LivejournalIcon,
  42. ViberIcon,
  43. WorkplaceIcon,
  44. LineIcon,
  45. PocketIcon,
  46. InstapaperIcon,
  47. WeiboIcon,
  48. } from "react-share";
Available Social sites are,
  1. Facebook
  2. Pinterest
  3. VK
  4. OK
  5. Reddit
  6. Tumblr
  7. FacebookMessenger
  8. Linkedin
  9. Twitter
  10. Telegram
  11. Whatsapp
  12. Email
  13. Livejournal
  14. Mailru
  15. Viber
  16. Workplace
  17. Line
  18. Weibo
  19. Pocket
  20. Instapaper
In the import statement
  • suffix sharebutton refers the api for share
  • suffixicon refers the icon of the social site
  • suffixcount refers the count of the share
Challenges
In v4 of typescript it gets a type error as follows:
  1. Type '{ children: Element; url: string; }' is missing the following properties from type 'Pick<Props<{ quote?: string; hashtag?: string; }>, "form" | "style" | "title" | "type" | "name" | "defaultChecked" | "defaultValue" | "suppressContentEditableWarning" | "suppressHydrationWarning" | ... 264 more ... | "resetButtonStyle">': form, title, type, name, and 256 more.
Workaround
In the node modules path (i.e. node_modules\react-share\es) open all the d.ts files and comment the export default method and replace with
  1. declare module 'react-share' {
  2. declare const ComonentName: any;
  3. export {
  4. ComonentName
  5. }
  6. }
For eg let's take FacebookShareButton.d.ts
Intially it will look like:
  1. /// <reference types="react" />
  2. declare const FacebookShareButton: import("react").ForwardRefExoticComponent<Pick<import("./ShareButton").Props<{
  3. quote?: string | undefined;
  4. hashtag?: string | undefined;
  5. }>, "disabled" | "hidden" | "dir" | "form" | "slot" | "style" | "title" | "color" | "children" | "url" | "className" | "id" | "lang" | "name" | "type" | "role" | "tabIndex" | "aria-activedescendant" | "aria-atomic" | "aria-autocomplete" | "aria-busy" | "aria-checked" | "aria-colcount" | "aria-colindex" | "aria-colspan" | "aria-controls" | "aria-current" | "aria-describedby" | "aria-details" | "aria-disabled" | "aria-dropeffect" | "aria-errormessage" | "aria-expanded" | "aria-flowto" | "aria-grabbed" | "aria-haspopup" | "aria-hidden" | "aria-invalid" | "aria-keyshortcuts" | "aria-label" | "aria-labelledby" | "aria-level" | "aria-live" | "aria-modal" | "aria-multiline" | "aria-multiselectable" | "aria-orientation" | "aria-owns" | "aria-placeholder" | "aria-posinset" | "aria-pressed" | "aria-readonly" | "aria-relevant" | "aria-required" | "aria-roledescription" | "aria-rowcount" | "aria-rowindex" | "aria-rowspan" | "aria-selected" | "aria-setsize" | "aria-sort" | "aria-valuemax" | "aria-valuemin" | "aria-valuenow" | "aria-valuetext" | "dangerouslySetInnerHTML" | "onCopy" | "onCopyCapture" | "onCut" | "onCutCapture" | "onPaste" | "onPasteCapture" | "onCompositionEnd" | "onCompositionEndCapture" | "onCompositionStart" | "onCompositionStartCapture" | "onCompositionUpdate" | "onCompositionUpdateCapture" | "onFocus" | "onFocusCapture" | "onBlur" | "onBlurCapture" | "onChange" | "onChangeCapture" | "onBeforeInput" | "onBeforeInputCapture" | "onInput" | "onInputCapture" | "onReset" | "onResetCapture" | "onSubmit" | "onSubmitCapture" | "onInvalid" | "onInvalidCapture" | "onLoad" | "onLoadCapture" | "onError" | "onErrorCapture" | "onKeyDown" | "onKeyDownCapture" | "onKeyPress" | "onKeyPressCapture" | "onKeyUp" | "onKeyUpCapture" | "onAbort" | "onAbortCapture" | "onCanPlay" | "onCanPlayCapture" | "onCanPlayThrough" | "onCanPlayThroughCapture" | "onDurationChange" | "onDurationChangeCapture" | "onEmptied" | "onEmptiedCapture" | "onEncrypted" | "onEncryptedCapture" | "onEnded" | "onEndedCapture" | "onLoadedData" | "onLoadedDataCapture" | "onLoadedMetadata" | "onLoadedMetadataCapture" | "onLoadStart" | "onLoadStartCapture" | "onPause" | "onPauseCapture" | "onPlay" | "onPlayCapture" | "onPlaying" | "onPlayingCapture" | "onProgress" | "onProgressCapture" | "onRateChange" | "onRateChangeCapture" | "onSeeked" | "onSeekedCapture" | "onSeeking" | "onSeekingCapture" | "onStalled" | "onStalledCapture" | "onSuspend" | "onSuspendCapture" | "onTimeUpdate" | "onTimeUpdateCapture" | "onVolumeChange" | "onVolumeChangeCapture" | "onWaiting" | "onWaitingCapture" | "onAuxClick" | "onAuxClickCapture" | "onClick" | "onClickCapture" | "onContextMenu" | "onContextMenuCapture" | "onDoubleClick" | "onDoubleClickCapture" | "onDrag" | "onDragCapture" | "onDragEnd" | "onDragEndCapture" | "onDragEnter" | "onDragEnterCapture" | "onDragExit" | "onDragExitCapture" | "onDragLeave" | "onDragLeaveCapture" | "onDragOver" | "onDragOverCapture" | "onDragStart" | "onDragStartCapture" | "onDrop" | "onDropCapture" | "onMouseDown" | "onMouseDownCapture" | "onMouseEnter" | "onMouseLeave" | "onMouseMove" | "onMouseMoveCapture" | "onMouseOut" | "onMouseOutCapture" | "onMouseOver" | "onMouseOverCapture" | "onMouseUp" | "onMouseUpCapture" | "onSelect" | "onSelectCapture" | "onTouchCancel" | "onTouchCancelCapture" | "onTouchEnd" | "onTouchEndCapture" | "onTouchMove" | "onTouchMoveCapture" | "onTouchStart" | "onTouchStartCapture" | "onPointerDown" | "onPointerDownCapture" | "onPointerMove" | "onPointerMoveCapture" | "onPointerUp" | "onPointerUpCapture" | "onPointerCancel" | "onPointerCancelCapture" | "onPointerEnter" | "onPointerEnterCapture" | "onPointerLeave" | "onPointerLeaveCapture" | "onPointerOver" | "onPointerOverCapture" | "onPointerOut" | "onPointerOutCapture" | "onGotPointerCapture" | "onGotPointerCaptureCapture" | "onLostPointerCapture" | "onLostPointerCaptureCapture" | "onScroll" | "onScrollCapture" | "onWheel" | "onWheelCapture" | "onAnimationStart" | "onAnimationStartCapture" | "onAnimationEnd" | "onAnimationEndCapture" | "onAnimationIteration" | "onAnimationIterationCapture" | "onTransitionEnd" | "onTransitionEndCapture" | "value" | "disabledStyle" | "openShareDialogOnClick" | "windowWidth" | "windowHeight" | "windowPosition" | "beforeOnClick" | "onShareWindowClose" | "resetButtonStyle" | "autoFocus" | "formAction" | "formEncType" | "formMethod" | "formNoValidate" | "formTarget" | "defaultChecked" | "defaultValue" | "suppressContentEditableWarning" | "suppressHydrationWarning" | "accessKey" | "contentEditable" | "contextMenu" | "draggable" | "placeholder" | "spellCheck" | "translate" | "radioGroup" | "about" | "datatype" | "inlist" | "prefix" | "property" | "resource" | "typeof" | "vocab" | "autoCapitalize" | "autoCorrect" | "autoSave" | "itemProp" | "itemScope" | "itemType" | "itemID" | "itemRef" | "results" | "security" | "unselectable" | "inputMode" | "is"> & {
  6. quote?: string | undefined;
  7. hashtag?: string | undefined;
  8. } & import("react").RefAttributes<HTMLButtonElement>>;
  9. export default FacebookShareButton;
After updating it will look like:
  1. /// <reference types="react" />
  2. declare const FacebookShareButton: import("react").ForwardRefExoticComponent<Pick<import("./ShareButton").Props<{
  3. quote?: string | undefined;
  4. hashtag?: string | undefined;
  5. }>, "disabled" | "hidden" | "dir" | "form" | "slot" | "style" | "title" | "color" | "children" | "url" | "className" | "id" | "lang" | "name" | "type" | "role" | "tabIndex" | "aria-activedescendant" | "aria-atomic" | "aria-autocomplete" | "aria-busy" | "aria-checked" | "aria-colcount" | "aria-colindex" | "aria-colspan" | "aria-controls" | "aria-current" | "aria-describedby" | "aria-details" | "aria-disabled" | "aria-dropeffect" | "aria-errormessage" | "aria-expanded" | "aria-flowto" | "aria-grabbed" | "aria-haspopup" | "aria-hidden" | "aria-invalid" | "aria-keyshortcuts" | "aria-label" | "aria-labelledby" | "aria-level" | "aria-live" | "aria-modal" | "aria-multiline" | "aria-multiselectable" | "aria-orientation" | "aria-owns" | "aria-placeholder" | "aria-posinset" | "aria-pressed" | "aria-readonly" | "aria-relevant" | "aria-required" | "aria-roledescription" | "aria-rowcount" | "aria-rowindex" | "aria-rowspan" | "aria-selected" | "aria-setsize" | "aria-sort" | "aria-valuemax" | "aria-valuemin" | "aria-valuenow" | "aria-valuetext" | "dangerouslySetInnerHTML" | "onCopy" | "onCopyCapture" | "onCut" | "onCutCapture" | "onPaste" | "onPasteCapture" | "onCompositionEnd" | "onCompositionEndCapture" | "onCompositionStart" | "onCompositionStartCapture" | "onCompositionUpdate" | "onCompositionUpdateCapture" | "onFocus" | "onFocusCapture" | "onBlur" | "onBlurCapture" | "onChange" | "onChangeCapture" | "onBeforeInput" | "onBeforeInputCapture" | "onInput" | "onInputCapture" | "onReset" | "onResetCapture" | "onSubmit" | "onSubmitCapture" | "onInvalid" | "onInvalidCapture" | "onLoad" | "onLoadCapture" | "onError" | "onErrorCapture" | "onKeyDown" | "onKeyDownCapture" | "onKeyPress" | "onKeyPressCapture" | "onKeyUp" | "onKeyUpCapture" | "onAbort" | "onAbortCapture" | "onCanPlay" | "onCanPlayCapture" | "onCanPlayThrough" | "onCanPlayThroughCapture" | "onDurationChange" | "onDurationChangeCapture" | "onEmptied" | "onEmptiedCapture" | "onEncrypted" | "onEncryptedCapture" | "onEnded" | "onEndedCapture" | "onLoadedData" | "onLoadedDataCapture" | "onLoadedMetadata" | "onLoadedMetadataCapture" | "onLoadStart" | "onLoadStartCapture" | "onPause" | "onPauseCapture" | "onPlay" | "onPlayCapture" | "onPlaying" | "onPlayingCapture" | "onProgress" | "onProgressCapture" | "onRateChange" | "onRateChangeCapture" | "onSeeked" | "onSeekedCapture" | "onSeeking" | "onSeekingCapture" | "onStalled" | "onStalledCapture" | "onSuspend" | "onSuspendCapture" | "onTimeUpdate" | "onTimeUpdateCapture" | "onVolumeChange" | "onVolumeChangeCapture" | "onWaiting" | "onWaitingCapture" | "onAuxClick" | "onAuxClickCapture" | "onClick" | "onClickCapture" | "onContextMenu" | "onContextMenuCapture" | "onDoubleClick" | "onDoubleClickCapture" | "onDrag" | "onDragCapture" | "onDragEnd" | "onDragEndCapture" | "onDragEnter" | "onDragEnterCapture" | "onDragExit" | "onDragExitCapture" | "onDragLeave" | "onDragLeaveCapture" | "onDragOver" | "onDragOverCapture" | "onDragStart" | "onDragStartCapture" | "onDrop" | "onDropCapture" | "onMouseDown" | "onMouseDownCapture" | "onMouseEnter" | "onMouseLeave" | "onMouseMove" | "onMouseMoveCapture" | "onMouseOut" | "onMouseOutCapture" | "onMouseOver" | "onMouseOverCapture" | "onMouseUp" | "onMouseUpCapture" | "onSelect" | "onSelectCapture" | "onTouchCancel" | "onTouchCancelCapture" | "onTouchEnd" | "onTouchEndCapture" | "onTouchMove" | "onTouchMoveCapture" | "onTouchStart" | "onTouchStartCapture" | "onPointerDown" | "onPointerDownCapture" | "onPointerMove" | "onPointerMoveCapture" | "onPointerUp" | "onPointerUpCapture" | "onPointerCancel" | "onPointerCancelCapture" | "onPointerEnter" | "onPointerEnterCapture" | "onPointerLeave" | "onPointerLeaveCapture" | "onPointerOver" | "onPointerOverCapture" | "onPointerOut" | "onPointerOutCapture" | "onGotPointerCapture" | "onGotPointerCaptureCapture" | "onLostPointerCapture" | "onLostPointerCaptureCapture" | "onScroll" | "onScrollCapture" | "onWheel" | "onWheelCapture" | "onAnimationStart" | "onAnimationStartCapture" | "onAnimationEnd" | "onAnimationEndCapture" | "onAnimationIteration" | "onAnimationIterationCapture" | "onTransitionEnd" | "onTransitionEndCapture" | "value" | "disabledStyle" | "openShareDialogOnClick" | "windowWidth" | "windowHeight" | "windowPosition" | "beforeOnClick" | "onShareWindowClose" | "resetButtonStyle" | "autoFocus" | "formAction" | "formEncType" | "formMethod" | "formNoValidate" | "formTarget" | "defaultChecked" | "defaultValue" | "suppressContentEditableWarning" | "suppressHydrationWarning" | "accessKey" | "contentEditable" | "contextMenu" | "draggable" | "placeholder" | "spellCheck" | "translate" | "radioGroup" | "about" | "datatype" | "inlist" | "prefix" | "property" | "resource" | "typeof" | "vocab" | "autoCapitalize" | "autoCorrect" | "autoSave" | "itemProp" | "itemScope" | "itemType" | "itemID" | "itemRef" | "results" | "security" | "unselectable" | "inputMode" | "is"> & {
  6. quote?: string | undefined;
  7. hashtag?: string | undefined;
  8. } & import("react").RefAttributes<HTMLButtonElement>>;
  9. //export default FacebookShareButton;
  10. declare module 'react-share' {
  11. declare const FacebookShareButton: any;
  12. export {
  13. FacebookShareButton
  14. }
  15. }
Do it for all the d.ts files present in the "node_modules\react-share\es" location as per its component name.
Full code
In SpfxReactShare.tsx
  1. import * as React from 'react';
  2. import { ISpfxReactShareProps } from './ISpfxReactShareProps';
  3. import {
  4. FacebookShareButton,FacebookIcon,FacebookMessengerShareButton,FacebookMessengerIcon,TwitterShareButton,TwitterIcon,
  5. TelegramShareButton,TelegramIcon,WhatsappShareButton,WhatsappIcon,LinkedinShareButton,LinkedinIcon
  6. ,RedditShareButton,RedditIcon,TumblrShareButton,TumblrIcon,EmailShareButton,EmailIcon,ViberShareButton,ViberIcon,
  7. LineShareButton,LineIcon
  8. } from "react-share";
  9. import './mystyle.css';
  10. export default class SpfxReactShare extends React.Component<ISpfxReactShareProps, {}> {
  11. public render(): React.ReactElement<ISpfxReactShareProps> {
  12. const shareUrl = 'https://www.c-sharpcorner.com/members/madhan-thurai';
  13. const title = 'c-sharpcorner';
  14. const myhasttag=["Madhan","MadhanAPI"];
  15. return (
  16. <div >
  17. <div className="Demo__container">
  18. <div className="Demo__some-network">
  19. <FacebookShareButton
  20. className={"Demo__some-network__share-button"}
  21. hashtag ={"#Madhan"}
  22. url={shareUrl}
  23. quote={title}>
  24. <FacebookIcon size={32} round />
  25. </FacebookShareButton>
  26. </div>
  27. <div className="Demo__some-network">
  28. <FacebookMessengerShareButton
  29. url={shareUrl}
  30. appId="521270401588372"
  31. className="Demo__some-network__share-button"
  32. >
  33. <FacebookMessengerIcon size={32} round />
  34. </FacebookMessengerShareButton>
  35. </div>
  36. <div className="Demo__some-network">
  37. <TwitterShareButton
  38. url={shareUrl}
  39. title={title}
  40. className="Demo__some-network__share-button"
  41. hashtags={myhasttag}
  42. via ={"MadhanAPI"}
  43. >
  44. <TwitterIcon size={32} round />
  45. </TwitterShareButton>
  46. <div className="Demo__some-network__share-count"> </div>
  47. </div>
  48. <div className="Demo__some-network">
  49. <TelegramShareButton
  50. url={shareUrl}
  51. title={title}
  52. className="Demo__some-network__share-button"
  53. >
  54. <TelegramIcon size={32} round />
  55. </TelegramShareButton>
  56. <div className="Demo__some-network__share-count"> </div>
  57. </div>
  58. <div className="Demo__some-network">
  59. <WhatsappShareButton
  60. url={shareUrl}
  61. title={title}
  62. separator=":: "
  63. className="Demo__some-network__share-button"
  64. >
  65. <WhatsappIcon size={32} round />
  66. </WhatsappShareButton>
  67. <div className="Demo__some-network__share-count"> </div>
  68. </div>
  69. <div className="Demo__some-network">
  70. <LinkedinShareButton url={shareUrl} className="Demo__some-network__share-button">
  71. <LinkedinIcon size={32} round />
  72. </LinkedinShareButton>
  73. </div>
  74. <div className="Demo__some-network">
  75. <RedditShareButton
  76. url={shareUrl}
  77. title={title}
  78. windowWidth={660}
  79. windowHeight={460}
  80. className="Demo__some-network__share-button"
  81. >
  82. <RedditIcon size={32} round />
  83. </RedditShareButton>
  84. </div>
  85. <div className="Demo__some-network">
  86. <TumblrShareButton
  87. url={shareUrl}
  88. title={title}
  89. className="Demo__some-network__share-button"
  90. >
  91. <TumblrIcon size={32} round />
  92. </TumblrShareButton>
  93. </div>
  94. <div className="Demo__some-network">
  95. <EmailShareButton
  96. url={shareUrl}
  97. subject={title}
  98. body={shareUrl}
  99. className="Demo__some-network__share-button"
  100. >
  101. <EmailIcon size={32} round />
  102. </EmailShareButton>
  103. </div>
  104. <div className="Demo__some-network">
  105. <ViberShareButton
  106. url={shareUrl}
  107. title={title}
  108. className="Demo__some-network__share-button"
  109. >
  110. <ViberIcon size={32} round />
  111. </ViberShareButton>
  112. </div>
  113. <div className="Demo__some-network">
  114. <LineShareButton
  115. url={shareUrl}
  116. title={title}
  117. className="Demo__some-network__share-button"
  118. >
  119. <LineIcon size={32} round />
  120. </LineShareButton>
  121. </div>
  122. </div>
  123. </div>
  124. );
  125. }
  126. }
Where url refers links to share, quote refers quotes along share with link, and a hashtag specified by the developer to be added to the shared content. People will still have the opportunity to remove this hashtag in the dialog. The hashtag should include the hash symbol. Twitter provides hastags in the form of array.
For detailed options visit here
In mystyle.css:
  1. body {
  2. font-family: 'Arial', sans-serif;
  3. background-color: white;
  4. padding: 20px;
  5. }
  6. .Demo__some-network {
  7. vertical-align: top;
  8. display: inline-block;
  9. margin-right: 10px;
  10. text-align: center;
  11. }
  12. .Demo__some-network__share-count {
  13. display: inline-flex;
  14. justify-content: center;
  15. white-space: nowrap;
  16. overflow: visible;
  17. width: 0;
  18. margin-top: 3px;
  19. font-size: 12px;
  20. }
  21. .Demo__some-network__share-button {
  22. cursor: pointer;
  23. }
  24. .Demo__some-network__share-button:hover:not(:active) {
  25. opacity: 0.75;
  26. }
  27. .Demo__some-network__custom-icon {
  28. width:32px;
  29. height:32px;
  30. }
Some of the outputs
Share Icons
Facebook Timeline Share
Facebook Messenger Share
Linkedin share
Telegram share
Twitter Share

Conclusion

Hence we learned about initializing React social share component in Spfx forms using react-share plugin. I hope this helps someone. Happy coding :)