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.

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
-
Download: You can download the extension files here: fb-embed-decoder.zip
-
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.
- First, extract the contents of the downloaded
Once installed, the extension's icon will appear in your Chrome toolbar.
How to Use It
Using the extension is straightforward:
- Copy Embed Code: On a website, find the Facebook post that you want to get URL for
- Open Extension: Click the Facebook Embed Link Extractor icon in your Chrome toolbar. The popup will appear.
- Paste and Convert: Paste the copied
<iframe>
code into the text area within the popup. Then, click the "Convert" button. - 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":
- It takes the text from the input field.
- It uses a regular expression to find the
src
attribute within the pasted<iframe>
code. - From this
src
URL, it extracts the value of thehref
query parameter. - This
href
value (which is the URL encoded Facebook link) is then decoded usingdecodeURIComponent()
. - 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.