How To Get A Public URL To Any Facebook Post

Easily decode Facebook iframe embeds to get the original post or video URL — perfect for sharing, saving, or archiving.

·Matija Žiberna·
How To Get A Public URL To Any Facebook Post

Sharing a direct link to a Facebook post can sometimes be a bit tricky, especially when you only have its embed code from another website. The actual link gets tucked away and is URL encoded, making it not immediately usable. I ran into this a few times, so I put together a small Chrome extension to make extracting that link simpler.

It's designed to quickly pull out the clean, original URL for any Facebook post (video, image, text, etc.) when all you have is the <iframe> embed code.

Get the Extension

  1. Download: You can download the extension files here: fb-embed-decoder.zip

  2. Install in Chrome: Since this is a custom extension, you'll need to load it as an "unpacked extension."

    • First, extract the contents of the downloaded .zip file into a folder on your computer.
    • For clear instructions on how to load an unpacked extension in Chrome, please follow this guide: How to Load an Unpacked Chrome Extension on DevDiggers. During the "Load unpacked" step, simply select the folder where you extracted the extension files.

Once installed, the extension's icon will appear in your Chrome toolbar.

How to Use It

Using the extension is straightforward:

  1. Copy Embed Code: On a website, find the Facebook post that you want to get URL for Copy embed
  2. Open Extension: Click the Facebook Embed Link Extractor icon in your Chrome toolbar. The popup will appear. Screenshot of the Facebook Embed Link Extractor extension popup
  3. Paste and Convert: Paste the copied <iframe> code into the text area within the popup. Then, click the "Convert" button.
  4. Link Ready: The direct Facebook post URL will be extracted and shown. It's also automatically copied to your clipboard, and you'll see a confirmation. For convenience, the link is added to a history list in the popup.

A Bit About How It Works

If you're curious about what happens behind the scenes:

The Challenge with Embeds: Facebook embed codes typically use an <iframe>. The direct link to the actual Facebook post is contained within the <iframe>'s src attribute, specifically as a URL encoded value for a parameter named href. The main task for the extension is to isolate this href value and then decode it.

The manifest.json File: This file is standard for Chrome extensions. It tells Chrome basic information like the extension's name, version, which HTML file to use for its popup (popup.html), and what permissions it requires. For this extension, it requests storage permission (to save the history of converted links) and clipboardWrite permission (to copy the extracted link to your clipboard).

Here's the manifest.json content:

{
  "manifest_version": 3,
  "name": "Facebook Embed Link Extractor",
  "description": "Extract direct link from Facebook embedded iframes",
  "version": "1.0",
  "action": {
    "default_popup": "popup.html",
    "default_icon": {
      "16": "images/icon16.png",
      "48": "images/icon48.png",
      "128": "images/icon128.png"
    }
  },
  "permissions": ["storage", "clipboardWrite"],
  "icons": {
    "16": "images/icon16.png",
    "48": "images/icon48.png",
    "128": "images/icon128.png"
  }
}

The JavaScript (popup.js): This file contains the logic for the extension. When you click "Convert":

  1. It takes the text from the input field.
  2. It uses a regular expression to find the src attribute within the pasted <iframe> code.
  3. From this src URL, it extracts the value of the href query parameter.
  4. This href value (which is the URL encoded Facebook link) is then decoded using decodeURIComponent().
  5. The resulting clean URL is displayed, copied to the clipboard using navigator.clipboard.writeText(), and saved to local storage for the history feature.

Here is the full JavaScript code (popup.js):

document.addEventListener('DOMContentLoaded', function() {
  // DOM Elements
  const iframeInput = document.getElementById('iframe-input');
  const convertBtn = document.getElementById('convert-btn');
  const clearBtn = document.getElementById('clear-btn');
  const resultContainer = document.getElementById('result-container');
  const resultUrl = document.getElementById('result-url');
  const copyStatus = document.getElementById('copy-status');
  const errorContainer = document.getElementById('error-container');
  const historyList = document.getElementById('history-list');
  const clearHistoryBtn = document.getElementById('clear-history-btn');

  // Load history when popup opens
  loadHistory();

  // Event Listeners
  convertBtn.addEventListener('click', handleConvert);
  clearBtn.addEventListener('click', handleClear);
  clearHistoryBtn.addEventListener('click', handleClearHistory);

  // Main conversion function
  function handleConvert() {
    // Reset UI state
    hideElement(errorContainer);
    hideElement(resultContainer);
    hideElement(copyStatus);

    const iframeCode = iframeInput.value.trim();

    if (!iframeCode) {
      showError();
      return;
    }

    const fbUrl = extractFacebookVideoUrl(iframeCode);

    if (fbUrl) {
      // Show result
      resultUrl.textContent = fbUrl;
      showElement(resultContainer);

      // Copy to clipboard
      copyToClipboard(fbUrl);

      // Save to history
      saveToHistory(fbUrl);

      // Update history display
      loadHistory();
    } else {
      showError();
    }
  }

  // Extract Facebook URL from iframe code
  function extractFacebookVideoUrl(iframeHtml) {
    const srcMatch = iframeHtml.match(/src="([^"]+)"/);
    if (!srcMatch) return null;

    try {
      const srcUrl = new URL(srcMatch[1]);
      const hrefEncoded = srcUrl.searchParams.get("href");

      return hrefEncoded ? decodeURIComponent(hrefEncoded) : null;
    } catch (e) {
      console.error("Error parsing URL:", e);
      return null;
    }
  }

  // Copy text to clipboard
  function copyToClipboard(text) {
    navigator.clipboard.writeText(text).then(() => {
      showElement(copyStatus);
      setTimeout(() => {
        hideElement(copyStatus);
      }, 2000);
    }).catch(err => {
      console.error('Could not copy text: ', err);
    });
  }

  // Save URL to history
  function saveToHistory(url) {
    chrome.storage.local.get(['fbExtractorHistory'], function(result) {
      let history = result.fbExtractorHistory || [];

      // Add new entry to the beginning
      history.unshift({
        url: url,
        timestamp: new Date().toISOString()
      });

      // Limit history to 10 items
      if (history.length > 10) {
        history = history.slice(0, 10);
      }

      chrome.storage.local.set({ fbExtractorHistory: history });
    });
  }

  // Load and display history
  function loadHistory() {
    chrome.storage.local.get(['fbExtractorHistory'], function(result) {
      const history = result.fbExtractorHistory || [];

      // Clear existing list
      historyList.innerHTML = '';

      if (history.length === 0) {
        const emptyItem = document.createElement('li');
        emptyItem.textContent = 'No history yet';
        emptyItem.style.color = '#65676b';
        emptyItem.style.textAlign = 'center';
        emptyItem.style.cursor = 'default';
        historyList.appendChild(emptyItem);
        return;
      }

      // Add each history item
      history.forEach(item => {
        const li = document.createElement('li');

        const urlSpan = document.createElement('span');
        urlSpan.className = 'history-url';
        urlSpan.textContent = item.url;

        const timeSpan = document.createElement('span');
        timeSpan.className = 'history-time';
        timeSpan.textContent = formatDate(new Date(item.timestamp));

        li.appendChild(urlSpan);
        li.appendChild(timeSpan);

        // Add click event to copy URL
        li.addEventListener('click', function() {
          copyToClipboard(item.url);
        });

        historyList.appendChild(li);
      });
    });
  }

  // Format date to readable string
  function formatDate(date) {
    const now = new Date();
    const diff = now - date;

    // Less than a day
    if (diff < 24 * 60 * 60 * 1000) {
      return date.toLocaleTimeString([], { hour: '2-digit', minute: '2-digit' });
    }

    // Less than a week
    if (diff < 7 * 24 * 60 * 60 * 1000) {
      const days = ['Sun', 'Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat'];
      return days[date.getDay()];
    }

    // More than a week
    return date.toLocaleDateString();
  }

  // Clear input and output
  function handleClear() {
    iframeInput.value = '';
    hideElement(resultContainer);
    hideElement(errorContainer);
    iframeInput.focus();
  }

  // Clear history
  function handleClearHistory() {
    chrome.storage.local.remove(['fbExtractorHistory'], function() {
      loadHistory();
    });
  }

  // Utility function to show element
  function showElement(element) {
    element.classList.remove('hidden');
  }

  // Utility function to hide element
  function hideElement(element) {
    element.classList.add('hidden');
  }

  // Show error message
  function showError() {
    showElement(errorContainer);
  }
});

Source Code

The complete source code, including the popup.html and popup.css files for the extension's interface, is available on GitHub: https://github.com/matija2209/fb-embed-link-extractor


I made this tool because it was a small annoyance I wanted to solve for myself. Hopefully, it can save you a bit of time too if you ever need to grab those direct Facebook links from embed codes.

9
Enjoyed this article?
Subscribe to my newsletter for more insights and tutorials.
Matija Žiberna
Matija Žiberna
Full-stack developer, co-founder

I'm Matija Žiberna, a self-taught full-stack developer and co-founder passionate about building products, writing clean code, and figuring out how to turn ideas into businesses. I write about web development with Next.js, lessons from entrepreneurship, and the journey of learning by doing. My goal is to provide value through code—whether it's through tools, content, or real-world software.

You might be interested in