To add a Youtube Gallery to Squarespace, like this.
#1. First, add a Markdown Block with Youtube URLs
#2. Next, find Markdown Block ID
#3. Next, use this code to Custom CSS
You can also use this Youtube Gallery free widget, you can add Youtube Gallery easier to Squarespace without complex code.
/* Youtube Grid Video */
.youtube-gallery-grid {
display: grid;
gap: 20px;
width: 100%;
margin: 20px 0;
}
.youtube-gallery-item {
position: relative;
width: 100%;
}
.youtube-video-container {
position: relative;
width: 100%;
padding-bottom: 56.25%;
background: #000;
border-radius: 8px;
overflow: hidden;
box-shadow: 0 4px 6px rgba(0, 0, 0, 0.1);
}
.youtube-video-iframe {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
border: none;
}
.youtube-play-button {
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
background: rgba(255, 0, 0, 0.9);
color: #fff;
border: none;
border-radius: 12px;
width: 80px;
height: 56px;
font-size: 0;
cursor: pointer;
z-index: 10;
display: flex;
align-items: center;
justify-content: center;
transition: all 0.3s ease;
}
.youtube-play-button::before {
content: '';
width: 0;
height: 0;
border-style: solid;
border-width: 12px 0 12px 20px;
border-color: transparent transparent transparent #fff;
margin-left: 4px;
}
.youtube-play-button:hover {
background: rgba(255, 0, 0, 1);
transform: translate(-50%, -50%) scale(1.1);
}
@media (max-width: 768px) {
.youtube-gallery-grid {
grid-template-columns: 1fr !important;
gap: 15px;
}
}
#4. Use this code to Page Header Injection
<!-- @tuanphan Markdown Youtube Grid -->
<script>
const galleryConfig = {
blockId: '#block-yui_3_17_2_1_1760339695956_13713',
columns: 3,
gap: '20px'
};
(function() {
let videoPlayers = [];
let ytReady = false;
let initialized = false;
window.onYouTubeIframeAPIReady = function() {
ytReady = true;
initGallery();
};
function loadYouTubeAPI() {
if (window.YT && window.YT.Player) {
ytReady = true;
return;
}
const tag = document.createElement('script');
tag.src = 'https://www.youtube.com/iframe_api';
const firstScriptTag = document.getElementsByTagName('script')[0];
firstScriptTag.parentNode.insertBefore(tag, firstScriptTag);
}
function extractYouTubeId(url) {
const patterns = [
/(?:youtube\.com\/watch\?v=|youtu\.be\/)([^&\?\/]+)/,
/youtube\.com\/embed\/([^&\?\/]+)/,
/youtube\.com\/v\/([^&\?\/]+)/
];
for (let pattern of patterns) {
const match = url.match(pattern);
if (match) return match[1];
}
return null;
}
function createYouTubePlayer(containerId, videoId) {
if (!window.YT || !window.YT.Player) return null;
return new window.YT.Player(containerId, {
videoId: videoId,
playerVars: {
autoplay: 0,
controls: 1,
rel: 0,
modestbranding: 1,
playsinline: 1
},
events: {
onStateChange: function(event) {
const playerData = videoPlayers.find(p => p.player === event.target);
if (!playerData) return;
if (event.data === YT.PlayerState.PLAYING) {
playerData.playButton.style.display = 'none';
videoPlayers.forEach(p => {
if (p !== playerData && p.player) {
p.player.pauseVideo();
}
});
} else if (event.data === YT.PlayerState.PAUSED || event.data === YT.PlayerState.ENDED) {
playerData.playButton.style.display = 'flex';
}
}
}
});
}
function createGalleryItem(videoId, index) {
const item = document.createElement('div');
item.className = 'youtube-gallery-item';
const container = document.createElement('div');
container.className = 'youtube-video-container';
const iframeContainer = document.createElement('div');
iframeContainer.className = 'youtube-video-iframe';
iframeContainer.id = 'youtube-player-' + index;
const playButton = document.createElement('button');
playButton.className = 'youtube-play-button';
playButton.setAttribute('aria-label', 'Play video');
container.appendChild(iframeContainer);
container.appendChild(playButton);
item.appendChild(container);
playButton.addEventListener('click', function(e) {
e.preventDefault();
const playerData = videoPlayers[index];
if (playerData && playerData.player) {
playerData.player.playVideo();
}
});
return { item, iframeContainer, playButton };
}
function initGallery() {
if (initialized || !ytReady) return;
const block = document.querySelector(galleryConfig.blockId);
if (!block) {
console.log('Block not found: ' + galleryConfig.blockId);
return;
}
const links = block.querySelectorAll('a[href*="youtube.com"], a[href*="youtu.be"]');
if (links.length === 0) {
console.log('No YouTube links found in block');
return;
}
console.log('Found ' + links.length + ' YouTube videos');
const videoIds = [];
links.forEach(link => {
const videoId = extractYouTubeId(link.href);
if (videoId) videoIds.push(videoId);
});
if (videoIds.length === 0) return;
const galleryGrid = document.createElement('div');
galleryGrid.className = 'youtube-gallery-grid';
galleryGrid.style.gridTemplateColumns = `repeat(${galleryConfig.columns}, 1fr)`;
galleryGrid.style.gap = galleryConfig.gap;
videoIds.forEach((videoId, index) => {
const { item, iframeContainer, playButton } = createGalleryItem(videoId, index);
galleryGrid.appendChild(item);
setTimeout(() => {
const player = createYouTubePlayer(iframeContainer.id, videoId);
videoPlayers[index] = {
player: player,
playButton: playButton,
videoId: videoId
};
}, 100 * index);
});
const blockContent = block.querySelector('.sqs-block-content');
if (blockContent) {
blockContent.innerHTML = '';
blockContent.appendChild(galleryGrid);
}
initialized = true;
}
loadYouTubeAPI();
function checkAndInit() {
const block = document.querySelector(galleryConfig.blockId);
if (block && !initialized && ytReady) {
initGallery();
}
}
if (document.readyState === 'loading') {
document.addEventListener('DOMContentLoaded', function() {
setTimeout(checkAndInit, 1000);
setInterval(checkAndInit, 2000);
});
} else {
setTimeout(checkAndInit, 1000);
setInterval(checkAndInit, 2000);
}
})();
</script>
#5. Remember to update Markdown Block ID & number of columns.