Add Share buttons to your Blog¶
One feature that is currently missing from the Material for MkDocs Blog plugin1 are share buttons that would allow your readers to share your blog post on Social media platforms.
This guide will show you how you can implement this yourself!
Prerequisites¶
This Guide requires you to have knowledge in extending the Material for MkDocs theme as it requires changes to some of its pages.
Should you not have experience in theme extending can you read about it here.
1. Setting the button data¶
This setup will use values you set within your mkdocs.yml file, namely inside the extra option. In our case would we have the following values:
extra:
# Other values
share:
- link: 'https://example.com?text={title}&url={url}'
icon: 'material/share'
title: 'Share this Post!'
class: 'md-button__social--example'
We would iterate through the list of entries in share and use the values accordingly.
link would be the URL of the social media site where you want to share your post. {title} and {url} would be replaced with specific values.
icon would be an SVG icon offered by Material for MkDocs. Basically any icon that can be found in .icons/ would be usable, meaning you could also use your own if you set some.
title would be the text used for the title attribute of the Link Element.
class would be classes that get added alongside md-button and md-button__social (More on that later).
You can of course choose a different aproach of providing values, or even hard-code them into the template itself. I chose this aproach as it is a simple way of adding or removing share button when needed.
2. Creating share.html¶
The first thing you should do is create a new template file.
I call mine share.html and put it in <custom_dir>/partials/ (<custom_dir> being the theme -> custom_dir folder you've set in your mkdocs.yml file). You could also edit the blog-post.html file directly, but a separate file can make it easier for you to edit and maintain, which is why I chose this aproach.
Once you've created the file, would you add the following content to it:
{% if config.extra and config.extra.share %}
Share this Post:<br>
{% for entry in config.extra.share %}
{% set page_title = page.title | urlencode %}
{% set url = share.link | replace("{url}", page.canonical_url) | replace("{title}", page_title) %}
{% set icon = share.icon | d("material/share") %}
<a href="{{ url }}" class="md-button md-button__social {{ share.class | d('md-button--primary') }}" title="{{ share.title | d('Share this Post!') }}" target="_blank" rel="noopener">
{% include ".icons/" ~ icon ~ ".svg" %}
</a>
{% endfor %}
{% endif %}
Here is how it works: The template first checks if the extra config option exists and if it contains share. Should this be the case will it go through each entry of the share option.
For each option would it do the following:
- Get the page Title and URL Encode it to use later in the final
hrefvalue. - Get the
share.linkvalue defined and replace{url}with the canonical page URL and{title}with the previously retrieved page title. - Get the
share.iconto use, defaulting tomaterial/share() if none is found. - Create a
aHTML element containing the following:hrefbeing set to the previously createdurlobject.classbeing set tomd-button md-button__socialand either the value provided throughshare.classormd-button--primaryif not set.titlebeing set to the value ofshare.title, defaulting toShare this Post!if none is found.target="_blank"andrel="noopener"to open the links in new tabs.
This would now create buttons one can click to open a Link to share your blog post. However, the template file isn't used yet and also doesn't look that appealing, which we will work on in the next sections.
3. Use the share.html template¶
Making a dedicated share.html now gives us the freedom of choosing where the buttons should actually be displayed.
In this example will I add an additional section to the left sidebar of blog-post.html, right under the Metadata section, to display the buttons. This requires me to copy the content of blog-post.html2 to extend and customize it.
The result of implementing the template would look something similar to this:
<!-- -->
<!-- Parts of this file have been omitted for readibility. -->
<!-- Please check the original file for all the content. -->
<!-- -->
{% extends "main.html" %}
{% import "partials/nav-item.html" as item with context %}
{% block container %}
<div class="md-content md-content--post" data-md-component="content">
<div class="md-sidebar md-sidebar--post" data-md-component="sidebar" data-md-type="navigation">
<div class="md-sidebar__scrollwrap">
<div class="md-sidebar__inner md-post">
<nav class="md-nav md-nav--primary">
<!-- Omitted -->
<ul class="md-post__meta md-nav__list">
<!-- Omitted -->
<li>
<div class="md-post__title">
<span class="md-ellipsis">
Share
</span>
</div>
<nav class="md-nav">
<ul class="md-nav__list">
<li class="md-nav__item">
<div class="md-nav__link">
{% include "partials/share.html" %}
</div>
</li>
</ul>
</nav>
</li>
</ul>
<!-- Omitted -->
</nav>
{% if "toc.integrate" in features %}
{% include "partials/toc.html" %}
{% endif %}
</div>
</div>
</div>
<article class="md-content__inner md-typeset">
{% block content %}
{% include "partials/content.html" %}
{% endblock %}
</article>
</div>
{% endblock %}
This would add a section labeled Share right after the Metadata section, adding our Share template via {% include ... %} function of Jinja2.
You would now see the buttons, but their general style may look off. This can be fixed by making some extra CSS now.
4. Adding CSS¶
Our setup uses some unique classes: md-button__social and additional classes you would add via the share.class option. In our example are we using md-button__social--<platform> as class names for this option.
The md-button__social class is used to adjust certain attributes of the default md-button class which is used too. Some of these values include changing the line-height to 0 to have an equal padding around the icon itself, which we also set to .625em.
I suggest to use simple/... SVG icons, as they are all a consistent 24x24 pixels, allowing the bottom to have an equal height and width.
Here is an example CSS setup that contains common collors used for common social media platforms:
:root {
--md-button__mastodon: #6364FF;
--md-button__bluesky: #0886FE;
--md-button__twitter: #1DA1F2; /* (1) */
--md-button__facebook: #0866FF;
/* (2) */
--md-button__mastodon--lighter: #8283FF;
--md-button__bluesky--lighter: #399EFE;
--md-button__twitter--lighter: #4AB4F5; /* (3) */
--md-button__facebook--lighter: #3985FF;
}
.md-post .md-button.md-button__social {
line-height: 0;
padding: .625em;
color: white;
border-radius: .1rem; /* (4) */
}
.md-post .md-button.md-button_social:hover {
color: white; /* (5) */
}
.md-button.md-button__social--mastodon {
background-color: var(--md-button__mastodon);
border-color: var(--md-button__mastodon);
}
.md-button.md-button__social--bluesky {
background-color: var(--md-button__bluesky);
border-color: var(--md-button__bluesky);
}
.md-button.md-button__social--twitter {
background-color: var(--md-button__twitter);
border-color: var(--md-button__twitter);
}
.md-button.md-button__social--facebook {
background-color: var(--md-button__facebook);
border-color: var(--md-button__facebook);
}
.md-button.md-button__social--mastodon:hover {
background-color: var(--md-button__mastodon--lighter);
border-color: var(--md-button__mastodon--lighter);
}
.md-button.md-button__social--bluesky:hover {
background-color: var(--md-button__bluesky--lighter);
border-color: var(--md-button__bluesky--lighter);
}
.md-button.md-button__social--twitter:hover {
background-color: var(--md-button__twitter--lighter);
border-color: var(--md-button__twitter--lighter);
}
.md-button.md-button__social--facebook:hover {
background-color: var(--md-button__facebook--lighter);
border-color: var(--md-button__facebook--lighter);
}
- If you want to use X branding colors, change this to
#000. - These colors are used when hovering over the buttons to "highlight" them.
- If you want to use X branding colors, change this to
#333. - The border radius isn't applied within
md-postso we have to re-apply it here. - The color for hovering is being changed in
md-postso we have to force it back to white here.
Note
Don't forget to add this File as extra_css to your mkdocs.yml file!
You can now use f.e. md-button__social--mastodon to have the button use the Mastodon brand color as its background.
You're done¶
That should be it!
If you followed this tutorial should you have the following:
- A
share.htmlfile located at<custom_dir>/partials/ - A
blog-post.htmlfile located at<custom_dir>/including theshare.htmltemplate via{% include "partials/share.html" %} - A
share.cssfile located in the assets folder of yourdocs_dirand added to yourmkdocs.ymlasextra_css - A
shareoption insideextraof yourmkdocs.ymlfile containing entries for individual sites.
As an example are here the share values used for this blog:
extra:
share:
- link: 'https://mastodonshare.com/?url={url}&text={title}'
icon: 'simple/mastodon'
title: 'Toot Post on Mastodon!'
class: 'md-button__social--mastodon'
- link: 'https://bsky.app/intent/compose?text={title}%0A{url}'
icon: 'simple/bluesky'
title: 'Share Post on Bluesky!'
class: 'md-button__social--bluesky'
For a working example can you look at the sidebar of this post which should display the above links as buttons.
Share Links¶
Here is a quick collection of common social media platforms and the recommended links to use.
Mastodon¶
Recommended Link: https://mastodonshare.com/?url={url}&text={title}
Mastodon offers a share option in the form of <instance_domain>/share?text=<text>.
However, due to its decentralized nature could the user sharing your post not use the same instance as you. Thankfully, the community created a solution in the form of mastodonshare.com which provides a main URL for sharing posts. The downside is, that the user has to first provide the instance Domain to be forwarded to its share link. This, however, is only a one-time thing as the site remembers the instance provided and redirects the user on their next visit.
Bluesky¶
Recommended Link: https://bsky.app/intent/compose?text={title}%0A{url}
Bluesky only provides a text query parameter, requiring us to use URL encoded values in the final URL if we want to include both {title} and {url}.
We use %0A which is a URL-encoded newline and is treated as a space character by Bluesky. You may also use %20 for an actual Space character. Keep in mind that adding multiple of %0A won't add multiple newlines as Bluesky will strip them from the Compose UI.
Twitter¶
Recommended Link: https://twitter.com/intent/tweet?url={url}&text={title}
I personally recommend to not support Twitter anymore by adding a Share button to it. But if you want, then the above URL would be the one you should use.
Footnotes
Comments
Comment system powered by Mastodon.
Leave a comment using Mastodon or another Fediverse-compatible account.