Privacy-aware social sharing

Including external resources for online social sharing buttons is not desirable for privacy reasons. Using local webfonts or icons avoids such tracking.

Social share buttons usually are a privacy nightmare, as they often deliberately track every site visited. Most commonly, this is due to fetching remote resources such as fonts, scripts, or images from third parties that are not particularly well-known for their trustworthy privacy policies. By investing some tiny effort, this is not required, though.

Similar to when using e.g. Shariff, the need to create possibly unwanted remote connections can be made up for by using local icons, API URL links, and color definitions. Social media platforms are thus contacted only upon actual sharing, putting the ownership of its browsing habits back to the visitor.

In addition, this method might also improve performance. Even when distributed from a CDN with high cache-hit rates, the common approach usually leads to additional delay due to foreign DNS/connection/HTTP(S) roundtrips. No need for any scripting support also yields better compatibility, a more steady page load, and less processing overhead.

Local Resources for Sharing Privacy

Nearly all predominant social media platforms provide an URL that can be used as “API” endpoint for a sharing process. The page to share and often its description can be passed along, such that a simple hyperlink to the respective platform is sufficient. There is thus no need for a (possibly remote) script or referring to the platform before any user interaction. API URL structures of some well-known social media sites can be found in the table below.

Sharing buttons are mostly associated with a certain icon or logo in a familiar color. Self-hosting the images, vector-graphics, or icon fonts needed for representing a particular social media site is pretty simple, though. As for scripts, pre-loading external images or icons is thus also not necessary.

Please note that even this unproblematic approach with respect to privacy might also be affected by adblockers with tracking prevention. This is due to their rather generic (and partly naïve) CSS, HTML, and URL pattern matching. In order to ensure proper layout, it is possible to obfuscate accordingly though.

Common Social Media Sites

The link URLs for sharing can often be found at the respective site’s developer or webmaster documentation. Fortunately, a collection of these is available on GitHub. Matching corporate design colors of many sites can be found at BrandColors. Appropriate icons can be taken from Font Awesome Brands that (like other ones) can easily be self-hosted as icon font or used as vector-graphics source.

The table below aggregates this information for some of the most commonly used sites. For the link target, adapt the variables URL, TITLE, and DESC to your current page accordingly.

More sharing options besides additional social networks could also be considered here. Apart from Email, further possibilities include RSS, bookmarks, or clipboard copy (requiring some scripting). When using icon fonts, the chosen font might not include proper icons for all desired options, though (e.g. for the Email mailto: link above). Another or complementary icon source would thus be needed. This restriction does not apply when extracting SVGs manually from multiple fonts beforehand.

Embedding Local Resources

The following example shows that we can embed fully functional sharing by only using some additional local CSS and HTML. To show an actual sharing button, use the corresponding link from the table above with a specific class inside the social class:

<div class="social">
    <a class="xx" href="https://…"></a>
    <a class="
</div>

For styling and icons, two approaches are presented, using webfonts or embedded SVGs.

Local Icon Font

The required CSS defines the classes chosen in the HTML part by taking the icon charcodes and (in this case) foreground colors from the table above. The icon font fa-brands.woff used in this example is assumed to be present in the same directory.

@font-face {
    font-family: fa-brands;
    src: url('fa-brands.woff') format('woff');
    font-display: block;
}

.social a {
    font-family: fa-brands;
    /* more styling here… */
}

.social a.tw:before { color: #1DA1F2; content: "\F099"; }
.social a.in:before { color: #0077B5; content: "\F0E1"; }
.social a.gp:before { color: #DC4E41; content: "\F0D5"; }
.social a.fl:before { color: #E12828; content: "\F44D"; }
.social a.fb:before { color: #3B5998; content: "\F39E"; }
.social a.wa:before { color: #4DC247; content: "\F232"; }
.social a.rd:before { color: #FF5700; content: "\F281"; }
.social a.vk:before { color: #6383A8; content: "\F189"; }
.social a.dg:before { color: #221E1E; content: "\F1A6"; }
.social a.tr:before { color: #37455C; content: "\F173"; }
.social a.bl:before { color: #F57D00; content: "\F37D"; }
.social a.xi:before { color: #1A7576; content: "\F168"; }
.social a.hn:before { color: #FF6600; content: "\F3AF"; }

If your layout would benefit from more coherently aligned icons or if you want to remove unneeded ones for performance reasons, there is also a project on how to strip and align webfont icons.

CSS-embedded SVG

Icon fonts have the disadvantage that they might not be supported by some browsers, might be blocked by some plugins, usually cause a redraw in current browsers once loaded, ship more icons than needed, cause an additional request, and do not provide a simple method for a graceful fallback. In order to overcome those limitations, one can directly embed the icon’s vector graphics into CSS as SVG-background.

Coloring SVG backgrounds can be problematic, though, as it requires possibly complicated CSS filters or shape outlines. But as the per-icon color should be fixed and we embed the svg anyhow, we can inject the fill color right away:

.social a {
    background-repeat: no-repeat;
    background-size: contain;
    background-position: center;
    /* more styling here… */
}

.social a.tw:before { background-image: url('data:image/svg+xml,%3Csvg%20xmlns=%22http:%2F%2Fwww.w3.org%2F2000%2Fsvg%22%20viewBox=%220%200%20512%20512%22%20fill=%22%231DA1F2%22%3E%3Cpath%20d=%22M459.37%20151.716c.325%204.548.325%209.097.325%2013.645%200%20138.72-105.583%20298.558-298.558%20298.558-59.452%200-114.68-17.219-161.137-47.106%208.447.974%2016.568%201.299%2025.34%201.299%2049.055%200%2094.213-16.568%20130.274-44.832-46.132-.975-84.792-31.188-98.112-72.772%206.498.974%2012.995%201.624%2019.818%201.624%209.421%200%2018.843-1.3%2027.614-3.573-48.081-9.747-84.143-51.98-84.143-102.985v-1.299c13.969%207.797%2030.214%2012.67%2047.431%2013.319-28.264-18.843-46.781-51.005-46.781-87.391%200-19.492%205.197-37.36%2014.294-52.954%2051.655%2063.675%20129.3%20105.258%20216.365%20109.807-1.624-7.797-2.599-15.918-2.599-24.04%200-57.828%2046.782-104.934%20104.934-104.934%2030.213%200%2057.502%2012.67%2076.67%2033.137%2023.715-4.548%2046.456-13.32%2066.599-25.34-7.798%2024.366-24.366%2044.833-46.132%2057.827%2021.117-2.273%2041.584-8.122%2060.426-16.243-14.292%2020.791-32.161%2039.308-52.628%2054.253z%22%2F%3E%3C%2Fsvg%3E'); }
.social a.in:before { background-image: url('data:image/svg+xml,%3Csvg%20xmlns=%22http:%2F%2Fwww.w3.org%2F2000%2Fsvg%22%20viewBox=%220%200%20448%20512%22%20fill=%22%230077B5%22%3E%3Cpath%20d=%22M100.28%20448H7.4V148.9h92.88zM53.79%20108.1C24.09%20108.1%200%2083.5%200%2053.8a53.79%2053.79%200%200%201%20107.58%200c0%2029.7-24.1%2054.3-53.79%2054.3zM447.9%20448h-92.68V302.4c0-34.7-.7-79.2-48.29-79.2-48.29%200-55.69%2037.7-55.69%2076.7V448h-92.78V148.9h89.08v40.8h1.3c12.4-23.5%2042.69-48.3%2087.88-48.3%2094%200%20111.28%2061.9%20111.28%20142.3V448z%22%2F%3E%3C%2Fsvg%3E'); }
.social a.gp:before { background-image: url('data:image/svg+xml,%3Csvg%20xmlns=%22http:%2F%2Fwww.w3.org%2F2000%2Fsvg%22%20viewBox=%220%200%20640%20512%22%20fill=%22%23DD4B39%22%3E%3Cpath%20d=%22M386.061%20228.496c1.834%209.692%203.143%2019.384%203.143%2031.956C389.204%20370.205%20315.599%20448%20204.8%20448c-106.084%200-192-85.915-192-192s85.916-192%20192-192c51.864%200%2095.083%2018.859%20128.611%2050.292l-52.126%2050.03c-14.145-13.621-39.028-29.599-76.485-29.599-65.484%200-118.92%2054.221-118.92%20121.277%200%2067.056%2053.436%20121.277%20118.92%20121.277%2075.961%200%20104.513-54.745%20108.965-82.773H204.8v-66.009h181.261zm185.406%206.437V179.2h-56.001v55.733h-55.733v56.001h55.733v55.733h56.001v-55.733H627.2v-56.001h-55.733z%22%2F%3E%3C%2Fsvg%3E'); }
.social a.fl:before { background-image: url('data:image/svg+xml,%3Csvg%20xmlns=%22http:%2F%2Fwww.w3.org%2F2000%2Fsvg%22%20viewBox=%220%200%20448%20512%22%20fill=%22%23E12828%22%3E%3Cpath%20d=%22M0%2032v448h448V32H0zm358.4%20179.2h-89.6v89.6h-89.6v89.6H89.6V121.6h268.8v89.6z%22%2F%3E%3C%2Fsvg%3E'); }
.social a.fb:before { background-image: url('data:image/svg+xml,%3Csvg%20xmlns=%22http:%2F%2Fwww.w3.org%2F2000%2Fsvg%22%20viewBox=%220%200%20264%20512%22%20fill=%22%233B5998%22%3E%3Cpath%20d=%22M215.8%2085H264V3.6C255.7%202.5%20227.1%200%20193.8%200%20124.3%200%2076.7%2042.4%2076.7%20120.3V192H0v91h76.7v229h94V283h73.6l11.7-91h-85.3v-62.7c0-26.3%207.3-44.3%2045.1-44.3z%22%2F%3E%3C%2Fsvg%3E'); }
.social a.wa:before { background-image: url('data:image/svg+xml,%3Csvg%20xmlns=%22http:%2F%2Fwww.w3.org%2F2000%2Fsvg%22%20viewBox=%220%200%20448%20512%22%20fill=%22%2325D366%22%3E%3Cpath%20d=%22M380.9%2097.1C339%2055.1%20283.2%2032%20223.9%2032c-122.4%200-222%2099.6-222%20222%200%2039.1%2010.2%2077.3%2029.6%20111L0%20480l117.7-30.9c32.4%2017.7%2068.9%2027%20106.1%2027h.1c122.3%200%20224.1-99.6%20224.1-222%200-59.3-25.2-115-67.1-157zm-157%20341.6c-33.2%200-65.7-8.9-94-25.7l-6.7-4-69.8%2018.3L72%20359.2l-4.4-7c-18.5-29.4-28.2-63.3-28.2-98.2%200-101.7%2082.8-184.5%20184.6-184.5%2049.3%200%2095.6%2019.2%20130.4%2054.1%2034.8%2034.9%2056.2%2081.2%2056.1%20130.5%200%20101.8-84.9%20184.6-186.6%20184.6zm101.2-138.2c-5.5-2.8-32.8-16.2-37.9-18-5.1-1.9-8.8-2.8-12.5%202.8-3.7%205.6-14.3%2018-17.6%2021.8-3.2%203.7-6.5%204.2-12%201.4-32.6-16.3-54-29.1-75.5-66-5.7-9.8%205.7-9.1%2016.3-30.3%201.8-3.7.9-6.9-.5-9.7-1.4-2.8-12.5-30.1-17.1-41.2-4.5-10.8-9.1-9.3-12.5-9.5-3.2-.2-6.9-.2-10.6-.2-3.7%200-9.7%201.4-14.8%206.9-5.1%205.6-19.4%2019-19.4%2046.3%200%2027.3%2019.9%2053.7%2022.6%2057.4%202.8%203.7%2039.1%2059.7%2094.8%2083.8%2035.2%2015.2%2049%2016.5%2066.6%2013.9%2010.7-1.6%2032.8-13.4%2037.4-26.4%204.6-13%204.6-24.1%203.2-26.4-1.3-2.5-5-3.9-10.5-6.6z%22%2F%3E%3C%2Fsvg%3E'); }
.social a.rd:before { background-image: url('data:image/svg+xml,%3Csvg%20xmlns=%22http:%2F%2Fwww.w3.org%2F2000%2Fsvg%22%20viewBox=%220%200%20512%20512%22%20fill=%22%23FF4500%22%3E%3Cpath%20d=%22M440.3%20203.5c-15%200-28.2%206.2-37.9%2015.9-35.7-24.7-83.8-40.6-137.1-42.3L293%2052.3l88.2%2019.8c0%2021.6%2017.6%2039.2%2039.2%2039.2%2022%200%2039.7-18.1%2039.7-39.7s-17.6-39.7-39.7-39.7c-15.4%200-28.7%209.3-35.3%2022l-97.4-21.6c-4.9-1.3-9.7%202.2-11%207.1L246.3%20177c-52.9%202.2-100.5%2018.1-136.3%2042.8-9.7-10.1-23.4-16.3-38.4-16.3-55.6%200-73.8%2074.6-22.9%20100.1-1.8%207.9-2.6%2016.3-2.6%2024.7%200%2083.8%2094.4%20151.7%20210.3%20151.7%20116.4%200%20210.8-67.9%20210.8-151.7%200-8.4-.9-17.2-3.1-25.1%2049.9-25.6%2031.5-99.7-23.8-99.7zM129.4%20308.9c0-22%2017.6-39.7%2039.7-39.7%2021.6%200%2039.2%2017.6%2039.2%2039.7%200%2021.6-17.6%2039.2-39.2%2039.2-22%20.1-39.7-17.6-39.7-39.2zm214.3%2093.5c-36.4%2036.4-139.1%2036.4-175.5%200-4-3.5-4-9.7%200-13.7%203.5-3.5%209.7-3.5%2013.2%200%2027.8%2028.5%20120%2029%20149%200%203.5-3.5%209.7-3.5%2013.2%200%204.1%204%204.1%2010.2.1%2013.7zm-.8-54.2c-21.6%200-39.2-17.6-39.2-39.2%200-22%2017.6-39.7%2039.2-39.7%2022%200%2039.7%2017.6%2039.7%2039.7-.1%2021.5-17.7%2039.2-39.7%2039.2z%22%2F%3E%3C%2Fsvg%3E'); }
.social a.vk:before { background-image: url('data:image/svg+xml,%3Csvg%20xmlns=%22http:%2F%2Fwww.w3.org%2F2000%2Fsvg%22%20viewBox=%220%200%20576%20512%22%20fill=%22%2345668E%22%3E%3Cpath%20d=%22M545%20117.7c3.7-12.5%200-21.7-17.8-21.7h-58.9c-15%200-21.9%207.9-25.6%2016.7%200%200-30%2073.1-72.4%20120.5-13.7%2013.7-20%2018.1-27.5%2018.1-3.7%200-9.4-4.4-9.4-16.9V117.7c0-15-4.2-21.7-16.6-21.7h-92.6c-9.4%200-15%207-15%2013.5%200%2014.2%2021.2%2017.5%2023.4%2057.5v86.8c0%2019-3.4%2022.5-10.9%2022.5-20%200-68.6-73.4-97.4-157.4-5.8-16.3-11.5-22.9-26.6-22.9H38.8c-16.8%200-20.2%207.9-20.2%2016.7%200%2015.6%2020%2093.1%2093.1%20195.5C160.4%20378.1%20229%20416%20291.4%20416c37.5%200%2042.1-8.4%2042.1-22.9%200-66.8-3.4-73.1%2015.4-73.1%208.7%200%2023.7%204.4%2058.7%2038.1%2040%2040%2046.6%2057.9%2069%2057.9h58.9c16.8%200%2025.3-8.4%2020.4-25-11.2-34.9-86.9-106.7-90.3-111.5-8.7-11.2-6.2-16.2%200-26.2.1-.1%2072-101.3%2079.4-135.6z%22%2F%3E%3C%2Fsvg%3E'); }
.social a.dg:before { background-image: url('data:image/svg+xml,%3Csvg%20xmlns=%22http:%2F%2Fwww.w3.org%2F2000%2Fsvg%22%20viewBox=%220%200%20512%20512%22%20fill=%22%231B1A19%22%3E%3Cpath%20d=%22M81.7%20172.3H0v174.4h132.7V96h-51v76.3zm0%20133.4H50.9v-92.3h30.8v92.3zm297.2-133.4v174.4h81.8v28.5h-81.8V416H512V172.3H378.9zm81.8%20133.4h-30.8v-92.3h30.8v92.3zm-235.6%2041h82.1v28.5h-82.1V416h133.3V172.3H225.1v174.4zm51.2-133.3h30.8v92.3h-30.8v-92.3zM153.3%2096h51.3v51h-51.3V96zm0%2076.3h51.3v174.4h-51.3V172.3z%22%2F%3E%3C%2Fsvg%3E'); }
.social a.tr:before { background-image: url('data:image/svg+xml,%3Csvg%20xmlns=%22http:%2F%2Fwww.w3.org%2F2000%2Fsvg%22%20viewBox=%220%200%20320%20512%22%20fill=%22%2335465C%22%3E%3Cpath%20d=%22M309.8%20480.3c-13.6%2014.5-50%2031.7-97.4%2031.7-120.8%200-147-88.8-147-140.6v-144H17.9c-5.5%200-10-4.5-10-10v-68c0-7.2%204.5-13.6%2011.3-16%2062-21.8%2081.5-76%2084.3-117.1.8-11%206.5-16.3%2016.1-16.3h70.9c5.5%200%2010%204.5%2010%2010v115.2h83c5.5%200%2010%204.4%2010%209.9v81.7c0%205.5-4.5%2010-10%2010h-83.4V360c0%2034.2%2023.7%2053.6%2068%2035.8%204.8-1.9%209-3.2%2012.7-2.2%203.5.9%205.8%203.4%207.4%207.9l22%2064.3c1.8%205%203.3%2010.6-.4%2014.5z%22%2F%3E%3C%2Fsvg%3E'); }
.social a.bl:before { background-image: url('data:image/svg+xml,%3Csvg%20xmlns=%22http:%2F%2Fwww.w3.org%2F2000%2Fsvg%22%20viewBox=%220%200%20448%20512%22%20fill=%22%23F57D00%22%3E%3Cpath%20d=%22M446.6%20222.7c-1.8-8-6.8-15.4-12.5-18.5-1.8-1-13-2.2-25-2.7-20.1-.9-22.3-1.3-28.7-5-10.1-5.9-12.8-12.3-12.9-29.5-.1-33-13.8-63.7-40.9-91.3-19.3-19.7-40.9-33-65.5-40.5-5.9-1.8-19.1-2.4-63.3-2.9-69.4-.8-84.8.6-108.4%2010C45.9%2059.5%2014.7%2096.1%203.3%20142.9%201.2%20151.7.7%20165.8.2%20246.8c-.6%20101.5.1%20116.4%206.4%20136.5%2015.6%2049.6%2059.9%2086.3%20104.4%2094.3%2014.8%202.7%20197.3%203.3%20216%20.8%2032.5-4.4%2058-17.5%2081.9-41.9%2017.3-17.7%2028.1-36.8%2035.2-62.1%204.9-17.6%204.5-142.8%202.5-151.7zm-322.1-63.6c7.8-7.9%2010-8.2%2058.8-8.2%2043.9%200%2045.4.1%2051.8%203.4%209.3%204.7%2013.4%2011.3%2013.4%2021.9%200%209.5-3.8%2016.2-12.3%2021.6-4.6%202.9-7.3%203.1-50.3%203.3-26.5.2-47.7-.4-50.8-1.2-16.6-4.7-22.8-28.5-10.6-40.8zm191.8%20199.8l-14.9%202.4-77.5.9c-68.1.8-87.3-.4-90.9-2-7.1-3.1-13.8-11.7-14.9-19.4-1.1-7.3%202.6-17.3%208.2-22.4%207.1-6.4%2010.2-6.6%2097.3-6.7%2089.6-.1%2089.1-.1%2097.6%207.8%2012.1%2011.3%209.5%2031.2-4.9%2039.4z%22%2F%3E%3C%2Fsvg%3E'); }
.social a.xi:before { background-image: url('data:image/svg+xml,%3Csvg%20xmlns=%22http:%2F%2Fwww.w3.org%2F2000%2Fsvg%22%20viewBox=%220%200%20384%20512%22%20fill=%22%23026466%22%3E%3Cpath%20d=%22M162.7%20210c-1.8%203.3-25.2%2044.4-70.1%20123.5-4.9%208.3-10.8%2012.5-17.7%2012.5H9.8c-7.7%200-12.1-7.5-8.5-14.4l69-121.3c.2%200%20.2-.1%200-.3l-43.9-75.6c-4.3-7.8.3-14.1%208.5-14.1H100c7.3%200%2013.3%204.1%2018%2012.2l44.7%2077.5zM382.6%2046.1l-144%20253v.3L330.2%20466c3.9%207.1.2%2014.1-8.5%2014.1h-65.2c-7.6%200-13.6-4-18-12.2l-92.4-168.5c3.3-5.8%2051.5-90.8%20144.8-255.2%204.6-8.1%2010.4-12.2%2017.5-12.2h65.7c8%200%2012.3%206.7%208.5%2014.1z%22%2F%3E%3C%2Fsvg%3E'); }
.social a.hn:before { background-image: url('data:image/svg+xml,%3Csvg%20xmlns=%22http:%2F%2Fwww.w3.org%2F2000%2Fsvg%22%20viewBox=%220%200%20448%20512%22%20fill=%22%23FF6600%22%3E%3Cpath%20d=%22M400%2032H48C21.5%2032%200%2053.5%200%2080v352c0%2026.5%2021.5%2048%2048%2048h352c26.5%200%2048-21.5%2048-48V80c0-26.5-21.5-48-48-48zM21.2%20229.2H21c.1-.1.2-.3.3-.4%200%20.1%200%20.3-.1.4zm218%2053.9V384h-31.4V281.3L128%20128h37.3c52.5%2098.3%2049.2%20101.2%2059.3%20125.6%2012.3-27%205.8-24.4%2060.6-125.6H320l-80.8%20155.1z%22%2F%3E%3C%2Fsvg%3E'); }

In especially for this approach, don’t forget to enable server-side compression for CSS files.

After downloading a webfont that provides the needed SVG images, the stylesheet can optionally be generated by a small script like the following:

for ICON in XX:foo.svg:FF0000 YY:bar.svg:00FF00 …; do
    CLASS="${ICON%%:*}"
    SVGNAME="${ICON%:*}"
    SVGNAME="${SVGNAME#*:}"
    COLOR="${ICON##*:}"

    SVG=`cat "$SVGNAME" | sed "s/>/ fill=\"#$COLOR\">/"`
    if which base64 &>/dev/null; then
        SVG=`base64 <<<"$SVG"`
        SVG="url('data:image/svg+xml;base64,$SVG')"
    elif which urlencode &>/dev/null; then
        SVG=`urlencode <<<"$SVG"`
        SVG="url('data:image/svg+xml,$SVG')"
    else
        SVG=`sed 's/%/%25/g ; s/ /%20/g ; s/"/%22/g ; s/</%3C/g ; s/>/%3E/g ; s/#/%23/g ; s#/#%2F#g' <<<"$SVG"`
        SVG="url('data:image/svg+xml,$SVG')"
    fi

    echo ".$CLASS { background-image: $SVG; } /* $SVGNAME:$COLOR */"
done