├── LICENSE ├── README.md ├── example.html ├── sharing_buttons.css ├── sharing_buttons.js └── sharing_buttons_white.css /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2018 QuadrupleA 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # private-secure-sharing-buttons 2 | 3 | Privacy-respecting, simple social sharing buttons in vanilla JavaScript. 4 | 5 | ## Introduction 6 | 7 | Most social-sharing-button services like [AddThis](https://addthis.com/) and [Shareaholic](https://shareaholic.com/) have little respect for your users' privacy, installing dozens of tracking cookies that follow your users around the web, and degrading the performance of your pages by making surreptitious requests in the background. Because of this, most adblockers now block them, making it hard for people to share your stuff at all. 8 | 9 | Most of the alternatives I found, like [Social Share Privacy](https://github.com/panzi/SocialSharePrivacy) which Bruce Schneier [uses on his blog](https://www.schneier.com/blog/archives/2013/03/changes_to_the.html), seemed a bit overengineered / overcomplicated, requiring node.js, build scripts, asset folders, several dependent libraries, code and settings split across multiple files, etc. 10 | 11 | I wrote this simple one-file script for use in my own projects, and thought I'd share it here for others to use too. 12 | 13 | It's written in native JavaScript, and doesn't require jQuery, React, Angular, or any other frameworks, which should make it easy to integrate into most sites. It installs no cookies, makes no additional HTTP requests, and does not call to any assets outside of your own server. It embeds some lightweight SVG icons from [Font Awesome](https://fontawesome.com) right in the JS file, and is styled using CSS that you can easily customize. It only notifies social networks when the visitor clicks a sharing icon. 14 | 15 | ## Examples 16 | 17 | Download the files and open `example.html` in a browser to see it in action. 18 | 19 | A live demo (scroll to bottom) is at: [tomrissacher.com](https://tomrissacher.com/) 20 | 21 | Screenshots of the two included styles: 22 | 23 | ![Screenshots](/../doc-images/screenshots.png?raw=true "Default style") 24 | 25 | ## Usage 26 | 27 | Add `sharing_buttons.js` and the CSS styles to your page. Then, do one of the following: 28 | 29 | ### Add buttons using data attributes: 30 | 31 | For this, no additional javascript is needed. Just add an element with `data-sharing-buttons="true"` and any other desired options prefixed by `data-`: 32 | 33 | ```html 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 |
45 | 46 | 47 | ``` 48 | 49 | ### Add buttons using javascript: 50 | 51 | For programmatic control, you can initialize buttons using `AddSharingButtons(selector, options)`: 52 | 53 | ```html 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 |
62 | 63 |
64 | 71 | 72 | 73 | ``` 74 | 75 | ### Options: 76 | 77 | I tried to keep the code and CSS simple, rather than provide a ton of options, to encourage developers to dig in and customize it themselves to suit their needs. 78 | 79 | Options are passed via `data-` attributes or the 2nd parameter to `AddSharingButtons()`. 80 | 81 | * __services__ 82 | * Space-separated list of services you want sharing buttons for. 83 | * Default: `'twitter facebook email reddit pinterest tumblr'` (all of them) 84 | * __url__ 85 | * URL you want to share. 86 | * Default: `location.href` 87 | * __title__ 88 | * Title used in the post (not used by all services). 89 | * Default: `document.title` 90 | * __text__ 91 | * Body text used in the post (not used by all services). 92 | * Default: meta description. 93 | * __image__ 94 | * Absolute URL to image used in the post (not used by all services). 95 | * Default: meta `og:image` tag. 96 | * __labelHtml__ 97 | * Label markup prefixing the buttons. 98 | * Default: `
Share this:
` 99 | 100 | ## Contributions 101 | 102 | Pull requests are welcome - new social network / sharing services, alternate icons and stylings, as well as fixes to any bugs or browser incompatibilities. 103 | 104 | Thanks and enjoy! 105 | 106 | 107 | -------------------------------------------------------------------------------- /example.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | Sharing Icons Example 7 | 8 | 9 | 10 |
13 | 14 | 15 | -------------------------------------------------------------------------------- /sharing_buttons.css: -------------------------------------------------------------------------------- 1 | /* Sharing buttons */ 2 | 3 | .sharing-buttons { 4 | text-align: center; 5 | } 6 | 7 | .sharing-buttons > .share-label { 8 | display: inline-block; 9 | vertical-align: middle; 10 | padding-right: 1em; 11 | color: white; 12 | } 13 | 14 | .sharing-buttons > a { 15 | display: inline-block; 16 | vertical-align: middle; 17 | position: relative; 18 | text-align: center; 19 | border-radius: 3px; 20 | margin-right: 6px; 21 | width: 25px; 22 | height: 25px; 23 | box-shadow: 0 0 5px #00000042; 24 | } 25 | 26 | .sharing-buttons > a > svg { 27 | display: inline-block; 28 | position: absolute; 29 | left: 15%; 30 | top: 15%; 31 | width: 70%; 32 | height: 70%; 33 | color: white; 34 | } 35 | 36 | .sharing-buttons > a.twitter { 37 | background-color: #55acee; 38 | } 39 | 40 | .sharing-buttons > a.facebook { 41 | background-color: #3b5998; 42 | } 43 | 44 | .sharing-buttons > a.email { 45 | background-color: #32506d; 46 | } 47 | 48 | .sharing-buttons > a.reddit { 49 | background-color: #ff4500; 50 | } 51 | 52 | .sharing-buttons > a.pinterest { 53 | background-color: #cb2027; 54 | } 55 | 56 | .sharing-buttons > a.tumblr { 57 | background-color: #32506d; 58 | } 59 | 60 | .sharing-buttons > a:hover { 61 | filter: brightness(115%); 62 | } 63 | -------------------------------------------------------------------------------- /sharing_buttons.js: -------------------------------------------------------------------------------- 1 | // Privacy-respecting, secure, and simple social sharing buttons in native JS. 2 | // Use them on your own projects: 3 | // https://github.com/QuadrupleA/private-secure-sharing-buttons 4 | 5 | // Adds sharing buttons inside the container elements selected by 'selector'. 6 | function AddSharingButtons(selector, options) { 7 | 8 | // Add defaults to 'options' where missing 9 | var OPTION_DEFAULTS = { 10 | services: 'twitter facebook email reddit pinterest tumblr', 11 | url: location.href, 12 | title: document.title, 13 | text: (document.querySelector('meta[name=description]') || {}).content || '', 14 | image: (document.querySelector('meta[property="og:image"]') || {}).content || '', 15 | labelHtml: '
Share this:
' 16 | }; 17 | for (var key in OPTION_DEFAULTS) { 18 | if (!options.hasOwnProperty(key)) { 19 | options[key] = OPTION_DEFAULTS[key]; 20 | } 21 | } 22 | 23 | // Icons below are courtesy Font Awesome Free ( https://fontawesome.com/license ) 24 | // under the CC BY 4.0 License ( https://creativecommons.org/licenses/by/4.0/ ) 25 | 26 | // Set up available services 27 | var AVAILABLE_SERVICES = { 28 | twitter: { 29 | baseLink: 'https://twitter.com/intent/tweet?', 30 | urlParams: { text: options.text, url: options.url }, 31 | windowParams: 'width=550,height=270', 32 | tooltip: 'Share on Twitter', 33 | iconHtml: '' 34 | }, 35 | facebook: { 36 | baseLink: 'https://www.facebook.com/sharer/sharer.php?', 37 | urlParams: { u: options.url }, 38 | windowParams: 'width=580,height=296', 39 | tooltip: 'Share on Facebook', 40 | iconHtml: '' 41 | }, 42 | email: { 43 | baseLink: 'mailto:?', 44 | urlParams: { subject: options.title, body: options.text + ' ' + options.url }, 45 | windowParams: '', 46 | tooltip: 'Share via email', 47 | iconHtml: '' 48 | }, 49 | reddit: { 50 | baseLink: 'https://www.reddit.com/submit?', 51 | urlParams: { url: options.url, title: options.title }, 52 | windowParams: '', 53 | tooltip: 'Share on Reddit', 54 | iconHtml: '' 55 | }, 56 | pinterest: { 57 | baseLink: 'https://pinterest.com/pin/create/button/?', 58 | urlParams: { url: options.url, media: options.image, description: options.title }, 59 | windowParams: '', 60 | tooltip: 'Share on Pinterest', 61 | iconHtml: '' 62 | }, 63 | tumblr: { 64 | baseLink: 'https://www.tumblr.com/widgets/share/tool?', 65 | urlParams: { canonicalUrl: options.url, title: options.title, caption: options.description }, 66 | windowParams: '', 67 | tooltip: 'Share on Tumblr', 68 | iconHtml: '' 69 | }, 70 | }; 71 | 72 | // For each selected button container... 73 | var containers = document.querySelectorAll(selector); 74 | for (var i = 0; i < containers.length; i++) { 75 | 76 | // Add the 'share this' label if present 77 | var container = containers[i]; 78 | container.innerHTML = options.labelHtml; 79 | 80 | // Add buttons for each chosen service 81 | options.services.split(' ').forEach(function(serviceName) { 82 | var service = AVAILABLE_SERVICES[serviceName]; 83 | var button = document.createElement('a'); 84 | var urlParams = []; 85 | for (var key in service.urlParams) { 86 | urlParams.push(key + '=' + encodeURIComponent(service.urlParams[key])); 87 | } 88 | button.href = service.baseLink + urlParams.join('&'); 89 | button.target = serviceName; 90 | button.className = serviceName; 91 | button.title = service.tooltip; 92 | button._windowParams = service.windowParams; 93 | button.addEventListener('click', function(e) { 94 | e.preventDefault(); 95 | window.open(this.href, this.target, this._windowParams); 96 | }); 97 | button.innerHTML = service.iconHtml; 98 | container.appendChild(button); 99 | }); 100 | 101 | } // next button container 102 | 103 | } // end AddSharingButtons() 104 | 105 | 106 | // Optional: on page load, adds sharing buttons to any element with the attribute: 107 | // data-sharing-buttons="true" 108 | // Options can be specified using the attributes: 109 | // data-="" 110 | document.addEventListener('DOMContentLoaded', function() { 111 | var containers = document.querySelectorAll('[data-sharing-buttons=true]'); 112 | for (var i = 0; i < containers.length; i++) { 113 | var container = containers[i]; 114 | if (!container.id) { 115 | container.id = '_SharingButtons' + i; 116 | } 117 | var options = {}; 118 | ['services', 'url', 'title', 'text', 'image', 'labelHtml'].forEach(function(key) { 119 | var value = container.getAttribute('data-' + key); 120 | if (value) { 121 | options[key] = value; 122 | } 123 | }); 124 | AddSharingButtons('#' + container.id, options); 125 | } 126 | }, { once : true }); 127 | -------------------------------------------------------------------------------- /sharing_buttons_white.css: -------------------------------------------------------------------------------- 1 | .sharing-buttons { 2 | text-align: center; 3 | } 4 | 5 | .sharing-buttons > .share-label { 6 | display: inline-block; 7 | vertical-align: middle; 8 | padding-right: 1em; 9 | color: white; 10 | } 11 | 12 | .sharing-buttons > a { 13 | display: inline-block; 14 | vertical-align: middle; 15 | position: relative; 16 | text-align: center; 17 | border-radius: 3px; 18 | margin-right: 6px; 19 | width: 26px; 20 | height: 26px; 21 | background-color: white; 22 | transition: background-color 0.5s; 23 | } 24 | 25 | .sharing-buttons > a > svg { 26 | display: inline-block; 27 | position: absolute; 28 | left: 14%; 29 | top: 14%; 30 | width: 72%; 31 | height: 72%; 32 | color: #b7b7b7; 33 | } 34 | 35 | .sharing-buttons > a.twitter:hover { 36 | background-color: #55acee; 37 | } 38 | 39 | .sharing-buttons > a.facebook:hover { 40 | background-color: #3b5998; 41 | } 42 | 43 | .sharing-buttons > a.email:hover { 44 | background-color: #32506d; 45 | } 46 | 47 | .sharing-buttons > a.reddit:hover { 48 | background-color: #ff4500; 49 | } 50 | 51 | .sharing-buttons > a.pinterest:hover { 52 | background-color: #cb2027; 53 | } 54 | 55 | .sharing-buttons > a.tumblr:hover { 56 | background-color: #32506d; 57 | } 58 | 59 | --------------------------------------------------------------------------------