Filter the URLs in Gutenberg Social Link Block

I’m a big fan of the social media icons block in WordPress:

Social media links are such a common design element, and it’s now one less thing to think about when building a new website. No more icon libraries or grainy PNGs of social media logos.

One downside of the social links block is that you have to manually enter the URLs every time you place them on a template, in the footer, etc. For a project I’m working on, we’re building a custom settings page where the user can enter basic business info- hours, location, Facebook page- and then we’ll dynamically populate it throughout the site. (I’m not using an ACF Options page for this, but you certainly could.)

To accomplish this, we’re going to take advantage of the render_block_* filter available in WordPress. By using the block name to build the filter, we’ll end up with something like this: add_filter( 'render_block_core/social-link', ... ) which will allow us to filter the $block_content – the actual HTML markup of the social link block as the page is rendering it.

Note that we’re filtering the core/social-link block, not the core/social-links block – that extra s at the end is for the parent block that holds all of the links in the row. We want to modify the inner block that contains the single link itself.

The general function will look something like this:

function filter_social_icons_block( $block_content, $block ) {
	// Do stuff.
	return $block_content;
add_filter( 'render_block_core/social-link', 'filter_social_icons_block', 10, 2 );
Code language: PHP (php)

The filter also provides us with a second argument: $block, the full block array, including the attribute values. This will be important because which social network service the block is rendering will be saved as an attribute value in there: $block['attrs']['service']. We check the service, looking for the social network we want to filter, and then swap out the URL.

To swap the actual URL, we’ll use the WP_HTML_Tag_Processor to find the link and set the href attribute:

if ( 'twitter' === $block['attrs']['service'] && '' !== $new_twitter_url ) {
	$new_content = new WP_HTML_Tag_Processor( $block_content );
	if ( $new_content->next_tag( 'a' ) ) {
		$new_content->set_attribute( 'href', $new_twitter_url );
	$block_content = $new_content->get_updated_html();
Code language: PHP (php)

And that’s basically it! Let’s put it all together:

The options here are pretty open. You could use this method to add a CSS class or force links to open in a new tab. You could show different social link URLs in different situations, for example swapping in an author’s personal Twitter link on a single blog post template.

Of course, there are some limitations: the social icons do have to be added to the template- you can’t dynamically pick which icons to display (at least not with this filter). But this is just one example of the flexibility available when you embrace the render_block filter. Just remember that the filter only runs on the front of your website, not in the block editor, so anything you do with it will not show up inside the editor, only on the final page render.

Update: Reader Nahuai Badiola pointed out an alternate method, where you add the URL to the attributes earlier using the render_block_data filter. I think I might actually prefer this approach (though there are definitely use cases when modifying the rendered block HTML is the way to do it). Since the URL is stored as a block attribute, we can just swap it out before the block is actually rendered. Here’s a link to his gist.

2 responses to “Filter the URLs in Gutenberg Social Link Block”

  1. Birgit Pauli-Haack Avatar
    Birgit Pauli-Haack

    Wouldn’t a synched pattern do the trick, too? Set it once, reuse everywhere? What am I missing?

    1. Brian Coords Avatar
      Brian Coords

      Yes that’s definitely a smart approach as well.

      In this specific case the social URLs (along with a lot of other data) are going to be populated dynamically from an external API when a new network site is launched, so the goal was to populate them without any manual changes to the editor.

Leave a Reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.