![[IMG-Add Social Links to the Sidebar of an Obsidian Publish Site-20250624215017919.png|600]] </br> --- I recently came up with a method to add links to your social media profiles to modify my Obsidian site. Here’s a guide to walk you through what modifications I did to make this possible. This method uses a combination of JavaScript (to create the elements) and CSS (to style them). **Preview of Social Links for Left Side Panel**</br> ![[IMG-Add Social Links to the Sidebar of an Obsidian Publish Site-20250624215018072.png|300]] </br> ### Step 1: Create the JavaScript (`publish.js`) The `publish.js` file is responsible for creating the HTML for the "Connect" box and its icons. It runs automatically every time a page is loaded on your site. **Sample of my Obsidian vault opened in VS Code**</br> ![[IMG-Add Social Links to the Sidebar of an Obsidian Publish Site-20250624215018125.png|300]] </br> 1. Use a code editor, like VS Code to open your Obsidian vault. 2. Inside that folder, create a file named `publish.js`. 3. Copy and paste the entire code block below into your `publish.js` file. 4. Inside code look for function insertSocialLinks(), and edit the social urls to match your own. </br> >[!Note] >This is a modified code sample taken from: > - https://lab.marconoris.com/obsidian/footer-customization > > This sample was discovered on the Obsidian discord channel. > The code sample contains lots of examples of other social profiles. </br> ** Code Block: Publish.js** ```js /** * @file publish.js * @description This script enhances an Obsidian Publish site by dynamically inserting frontmatter properties * @note origianl code modified from https://lab.marconoris.com/obsidian/footer-customization */ let publishIntervalId; /** * @function insertCustomProperties * @description Checks for frontmatter in the current note and injects it as styled elements * at the top of the page, below the main properties block. * @returns {boolean} Returns true if the task is complete (or not needed), false if the required * DOM elements are not yet available. */ function insertCustomProperties() { const frontmatterEl = document.querySelector(".frontmatter"); if (!frontmatterEl) return true; if ( frontmatterEl.nextElementSibling?.classList.contains( "custom-properties-container" ) ) return true; const frontmatter = app.site.cache.cache[app.currentFilepath]?.frontmatter; if (!frontmatter) return true; const author = frontmatter["author"]; const published = frontmatter["published"]; const updated = frontmatter["updated"]; const tags = frontmatter["tags"]; const authorUrl = "https://davidrusho.com/about_me"; const propertiesToDisplay = []; if (author) propertiesToDisplay.push( `<div class="property-item"> <a href="${authorUrl}" class="property-tag" target="_blank" rel="noopener" >Author: ${author}</a > </div>` ); if (published) propertiesToDisplay.push( `<div class="property-item"> <a href="#" class="property-tag" target="_blank" rel="noopener" >Published: ${published.replaceAll("-", ".")}</a > </div>` ); if (updated) propertiesToDisplay.push( `<div class="property-item"> <a href="#" class="property-tag" target="_blank" rel="noopener" >updated: ${updated.replaceAll("-", ".")}</a > </div>` ); if (tags && Array.isArray(tags) && tags.length > 0) { const tagLinks = tags .map( (tag) => `<a href="/#${encodeURIComponent(tag)}" class="tag" target="_blank" rel="noopener" >#${tag}</a>` ) .join(" "); propertiesToDisplay.push( `<div class="property-item property-tags-container"> <span class="tags-label">Tags:</span ><span class="tags-values">${tagLinks}</span> </div>` ); } if (propertiesToDisplay.length > 0) { frontmatterEl.insertAdjacentHTML( "afterend", `<div class="custom-properties-container">${propertiesToDisplay.join( "" )}</div>` ); } return true; } /** * @function insertSocialLinks * @description Finds the theme-toggle button in the sidebar and injects a styled "Connect" box * with social media icons directly after it. * @returns {boolean} Returns true if the task is complete (or not needed), false if the required * DOM elements are not yet available. */ function insertSocialLinks() { const siteThemeToggleEl = document.querySelector( ".site-body-left-column-site-theme-toggle" ); if (!siteThemeToggleEl) { return false; } if (document.querySelector(".sidebar-social-container")) { return true; } // >>> EDIT YOUR SOCIAL MEDIA LINKS HERE <<< const socials = [ { url: "https://github.com/drusho", // >>> REPLACE URL WITH YOUR OWN name: "GitHub", svg: `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16" role="img"> <path d="M8 0C3.58 0 0 3.58 0 8c0 3.54 2.29 6.53 5.47 7.59.4.07.55-.17.55-.38 0-.19-.01-.82-.01-1.49-2.01.37-2.53-.49-2.69-.94-.09-.23-.48-.94-.82-1.13-.28-.15-.68-.52-.01-.53.63-.01 1.08.58 1.23.82.72 1.21 1.87.87 2.33.66.07-.52.28-.87.51-1.07-1.78-.2-3.64-.89-3.64-3.95 0-.87.31-1.59.82-2.15-.08-.2-.36-1.02.08-2.12 0 0 .67-.21 2.2.82.64-.18 1.32-.27 2-.27.68 0 1.36.09 2 .27 1.53-1.04 2.2-.82 2.2-.82.44 1.1.16 1.92.08 2.12.51.56.82 1.27.82 2.15 0 3.07-1.87 3.75-3.65 3.95.29.25.54.73.54 1.48 0 1.07-.01 1.93-.01 2.2 0 .21.15.46.55.38A8.013 8.013 0 0 0 16 8c0-4.42-3.58-8-8-8z" ></path> </svg>`, }, { url: "https://linkedin.com/in/davidrusho", // >>> REPLACE URL WITH YOUR OWN name: "LinkedIn", svg: `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16" role="img"> <path d="M0 1.146C0 .513.526 0 1.175 0h13.65C15.474 0 16 .513 16 1.146v13.708c0 .633-.526 1.146-1.175 1.146H1.175C.526 16 0 15.487 0 14.854V1.146zm4.943 12.248V6.169H2.542v7.225h2.401zm-1.2-8.212c.837 0 1.358-.554 1.358-1.248-.015-.709-.52-1.248-1.342-1.248-.822 0-1.359.54-1.359 1.248 0 .694.521 1.248 1.327 1.248h.016zm4.908 8.212V9.359c0-.216.016-.432.08-.586.173-.431.568-.878 1.232-.878.869 0 1.216.662 1.216 1.634v3.865h2.401V9.25c0-2.22-1.184-3.252-2.764-3.252-1.274 0-1.845.7-2.165 1.193v.025h-.016a5.54 5.54 0 0 1 .016-.025V6.169h-2.4c.03.678 0 7.225 0 7.225h2.4z" ></path> </svg> `, }, ]; const socialLinksHTML = `<div class="sidebar-social-container"> <h3 class="sidebar-social-title">Connect</h3> <div class="sidebar-social-links"> ${socials .map( (s) => `<a href="${s.url}" target="_blank" rel="noopener" aria-label="${s.name}" title="${s.name}" >${s.svg}</a >` ) .join("")} </div> </div> `; siteThemeToggleEl.insertAdjacentHTML("afterend", socialLinksHTML); return true; } /** * @function runScriptsAndClearInterval * @description A controller function that runs all enhancement scripts. When all scripts * confirm they are finished, it clears the master interval timer. */ function runScriptsAndClearInterval() { try { const propertiesDone = insertCustomProperties(); const socialLinksDone = insertSocialLinks(); if (propertiesDone && socialLinksDone) { clearInterval(publishIntervalId); } } catch (e) { console.error("Publish script error:", e); clearInterval(publishIntervalId); } } /** * @function onChangeDOM * @description A callback for the MutationObserver that detects when a page navigation occurs * in Obsidian Publish and re-runs the scripts. * @param {MutationRecord[]} mutationsList - A list of mutations that were observed. * @param {MutationObserver} observer - The observer instance. */ const onChangeDOM = (mutationsList, observer) => { const pageChanged = mutationsList.some((mutation) => Array.from(mutation.addedNodes).some( (node) => node.nodeType === 1 && (node.matches(".page-header") || node.querySelector(".page-header")) ) ); if (pageChanged) { clearInterval(publishIntervalId); publishIntervalId = setInterval(runScriptsAndClearInterval, 100); } }; // --- Script Initialization --- const targetNode = document.querySelector( ".markdown-preview-sizer.markdown-preview-section" ); if (targetNode) { const observer = new MutationObserver(onChangeDOM); observer.observe(targetNode, { childList: true, subtree: true, }); } // Initial run for the first page load. publishIntervalId = setInterval(runScriptsAndClearInterval, 100); ``` </br> ### Step 2: Add the Styling (`publish.css`) The CSS code is used to add style to the "Connect" title, and icons. 1. Just as we did with `publish.js` , create a `publish.css` in your root folder using a code editor like VS Code. 2. Copy and paste the code below into `publish.css`. There isn’t anything to modify in the section, but feel free to play around with setting to make them fit your sites style. ```css /* |-------------------------------------------------------------------------- |-- Sidebar Social Links Styling |-------------------------------------------------------------------------- | Styles for the "Connect" box containing social media icons, | injected below the theme toggle in the left sidebar. */ /* The main container box for the social links section */ .sidebar-social-container { border: 1px solid var(--background-modifier-border); border-radius: 8px; padding: 8px 12px; margin-top: 1.5em; display: flex; align-items: center; justify-content: flex-start; gap: 16px; } /* The "Connect" title */ .sidebar-social-title { font-size: var(--font-small); font-weight: 500; color: var(--text-muted); letter-spacing: 0.05em; text-transform: uppercase; margin: 0; } /* The container for the icons */ .sidebar-social-links { display: flex; align-items: center; gap: 12px; } /* Style the SVG icons themselves */ .sidebar-social-links svg { width: 20px; height: 20px; fill: var(--text-muted); transition: all 0.2s ease-in-out; } /* Add a hover effect to the icons */ .sidebar-social-links a:hover svg { fill: var(--text-accent); transform: scale(1.1); } ``` </br> ### Step 3: Upload and Publish 1. Make sure to save the files (`publish.js` and `publish.css` inside your code editor. 2. Open Obsidian and go to **Settings** -> **Publish**. 3. In the "Publish changes" dialog, make sure your new/updated `publish.js` and `publish.css` files are selected for upload. 4. Click **"Publish"**. **Sample of Obsidian Publish Menu**</br> ![[IMG-Add Social Links to the Sidebar of an Obsidian Publish Site-20250624215018257.png|500]] Your site should now display the "Connect" box with your social links in the sidebar on every page.</br> ![[IMG-Add Social Links to the Sidebar of an Obsidian Publish Site-20250624215018072.png|400]] --- ## Resources </br> ### Related Articles Check out the other articles from **Obsidian Publish Recipes** series: %% DATAVIEW_PUBLISH_CONVERT start ```dataview LIST WITHOUT ID "**" + file.link + "** </br>" + description + "</br></br>" FROM "07 - Publish - Obsidian" WHERE publish = true AND file.name != "About Me" AND file.name != "Home" AND series = "Obsidian Publish Recipes" SORT date DESC ``` %% - **[[07 - Publish - Obsidian/Articles/Add Social Links to the Footer of an Obsidian Publish Site.md|Add Social Links to the Footer of an Obsidian Publish Site]]** </br>How to customize an Obsidian Publish site by adding a social media links to the footer. This guide uses simple JavaScript and CSS to "hijack" your theme's default footer, creating a clean footer that appears on every page.</br></br> - **[[07 - Publish - Obsidian/Articles/Add Social Links to the Sidebar of an Obsidian Publish Site.md|Add Social Links to the Sidebar of an Obsidian Publish Site]]** </br>Customize your Obsidian Publish site by adding social media icons to the sidebar. This step-by-step guide uses simple CSS and JavaScript to create a "Connect" box that appears on every page, enhancing your site's professional look.</br></br> - **[[07 - Publish - Obsidian/Articles/Obsidian Publish Workflow - Automating Publication Prep.md|Obsidian Publish Workflow - Automating Publication Prep]]** </br>Walkthrough of a Templater script to automate Obsidian Publish workflow. The script manages frontmatter properties and converts Dataview queries to static Markdown.</br></br> - **[[07 - Publish - Obsidian/Posts/Series/Series - Obsidian Publish Recipes.md|Series - Obsidian Publish Recipes]]** </br>Articles related to customizing Obsidian Publish sites using javascript and css.</br></br> %% DATAVIEW_PUBLISH_CONVERT end %%