To achieve a carousel of blog posts with features like this: scale + full colored of middle images, white/black color on other images (in Squarespace).
#1. First, find Blog Page URL
#2. Next, edit page where you want to place this carousel > Add this code to Page Header Injection
<!-- Carousel post - @tuanphan -->
<script>const BlogSyncComponent={templates:{grid:{container:`<section class="tp-wrap"><style>.tp-wrap{width:100%}.tp-grid{display:grid;grid-template-columns:2fr 1fr;grid-template-rows:repeat(3,1fr);height:100vh}.tp-item{position:relative;background-image:var(--img);background-size:cover;background-position:center;background-repeat:no-repeat}.tp-item::before{content:"";position:absolute;inset:0;background:rgb(0 0 0 / .75)}.tp-item--lg{grid-row:1 / span 3}.tp-link{position:absolute;inset:0;display:flex;align-items:center;justify-content:center;text-decoration:none;color:#fff;padding:24px;text-align:center;z-index:1}.tp-meta{display:flex;flex-direction:column;gap:0}.tp-meta--lg{max-width:min(680px,90%)}.tp-cat{font-size:12px;letter-spacing:.2em;opacity:.9;text-transform:uppercase}.tp-title{color:#fff;font-size:32px;line-height:1.1;font-weight:700;margin-top:0;margin-bottom:0}.tp-desc{font-size:14px;line-height:1.4;opacity:.9;margin:0}.tp-btn{display:inline-block;margin-top:14px;padding:8px 20px;border:1px solid #fff;border-radius:999px;font-size:13px;transition:all 0.3s ease;width:100px;margin-left:auto;margin-right:auto}.tp-btn:hover{background:#fff;color:#000}@media (max-width:1024px){.tp-title{font-size:28px}}@media (max-width:767px){.tp-grid{grid-template-columns:1fr;grid-template-rows:none;height:auto}.tp-item--lg{grid-row:auto}.tp-item{aspect-ratio:16 / 9}.tp-title{font-size:24px}}</style><div class="tp-grid"></div></section>`,mainItem:`<article class="tp-item tp-item--lg" style="--img:url('{blogImage}')"><a class="tp-link" href="{blogUrl}"><div class="tp-meta tp-meta--lg"><h2 class="tp-title">{blogTitle}</h2></div></a></article>`,smallItem:`<article class="tp-item" style="--img:url('{blogImage}')"><a class="tp-link" href="{blogUrl}"><div class="tp-meta"><h3 class="tp-title">{blogTitle}</h3></div></article>`},carousel:{container:`<section class="blog-carousel-wrap">
<style>.blog-carousel-wrap{width:100%;padding:30px 0}.carousel-container{position:relative;width:100%;max-width:800px;margin:0 auto;overflow:hidden;padding-top:30px}.carousel-wrapper{display:flex;transition:transform 0.3s ease;gap:10px}.carousel-item{flex:0 0 calc(33.333% - 7px);transition:all 0.3s ease;position:relative;cursor:pointer}.carousel-item img{width:100%;height:200px;object-fit:cover;border-radius:8px;filter:grayscale(100%);transition:filter 0.3s ease}.carousel-item.center{transform:translateY(-20px);z-index:5}.carousel-item.center img{height:240px;filter:grayscale(0%)}.carousel-text{position:absolute;bottom:10px;left:10px;right:10px;background:rgb(0 0 0 / .7);color:#fff;padding:8px 12px;border-radius:4px;font-size:14px;font-weight:500;opacity:0;transition:opacity 0.3s ease}.carousel-title{margin:0;font-size:14px;line-height:1.2;overflow:hidden;text-overflow:ellipsis;display:-webkit-box;-webkit-line-clamp:2;-webkit-box-orient:vertical;color:#fff!important}.carousel-item.center .carousel-text{opacity:1}.carousel-arrow{position:absolute;top:50%;transform:translateY(-50%);background:rgb(255 255 255 / .8);border:none;width:40px;height:40px;border-radius:50%;cursor:pointer;display:flex;align-items:center;justify-content:center;font-size:18px;z-index:10;transition:background 0.3s ease}.carousel-arrow:hover{background:rgb(255 255 255)}.carousel-arrow.left{left:10px}.carousel-arrow.right{right:10px}@media (max-width:768px){.carousel-item{flex:0 0 calc(50% - 5px)}.carousel-item img{height:150px}.carousel-item.center img{height:180px}.carousel-text{font-size:12px;padding:6px 8px}.carousel-title{font-size:12px}}@media (max-width:480px){.carousel-item{flex:0 0 calc(100% - 5px)}}</style><div class="carousel-container"><button class="carousel-arrow left">❮</button><button class="carousel-arrow right">❯</button><div class="carousel-wrapper"></div></div></section>`,item:`<div class="carousel-item" onclick="window.location.href='{blogUrl}'"><img src="{blogImage}" alt="{blogTitle}"><div class="carousel-text"><h3 class="carousel-title">{blogTitle}</h3></div></div>`}},initialize(){document.addEventListener('DOMContentLoaded',()=>{this.processComponents()})},processComponents(){const syncElements=document.querySelectorAll('[data-sync-blog-url]');syncElements.forEach(element=>{this.setupComponent(element)})},async setupComponent(element){const blogPath=element.getAttribute('data-sync-blog-url');const templateStyle=element.getAttribute('data-style')||'grid';const maxItems=parseInt(element.getAttribute('data-limit'))||5;const template=this.templates[templateStyle];if(!template){console.error(`Template "${templateStyle}" not found`);return}
element.innerHTML=template.container;try{const blogData=await this.fetchBlogData(blogPath,maxItems);if(templateStyle==='carousel'){this.populateCarouselItems(element,blogData,template);this.initializeCarousel(element,blogData.length)}else{this.populateGridItems(element,blogData,template)}}catch(error){console.error('Failed to load blog data:',error)}},async fetchBlogData(blogPath,maxItems){const response=await fetch(`${blogPath}?format=json`);const jsonData=await response.json();return jsonData.items.slice(0,maxItems).map((post,index)=>({blogTitle:post.title,blogUrl:post.fullUrl,blogImage:post.assetUrl,itemNumber:index+1}))},populateGridItems(element,blogPosts,template){const gridContainer=element.querySelector('.tp-grid');let htmlOutput='';blogPosts.forEach((post,index)=>{if(index===0){htmlOutput+=template.mainItem.replace(/{blogTitle}/g,post.blogTitle).replace(/{blogUrl}/g,post.blogUrl).replace(/{blogImage}/g,post.blogImage)}else{htmlOutput+=template.smallItem.replace(/{blogTitle}/g,post.blogTitle).replace(/{blogUrl}/g,post.blogUrl).replace(/{blogImage}/g,post.blogImage)}});gridContainer.innerHTML=htmlOutput},populateCarouselItems(element,blogPosts,template){const carouselWrapper=element.querySelector('.carousel-wrapper');let htmlOutput='';blogPosts.forEach((post)=>{htmlOutput+=template.item.replace(/{blogTitle}/g,post.blogTitle).replace(/{blogUrl}/g,post.blogUrl).replace(/{blogImage}/g,post.blogImage)});carouselWrapper.innerHTML=htmlOutput},initializeCarousel(element,totalItems){let currentIndex=0;const itemsPerView=window.innerWidth<=480?1:window.innerWidth<=768?2:3;const maxIndex=Math.max(0,totalItems-itemsPerView);const carouselWrapper=element.querySelector('.carousel-wrapper');const prevBtn=element.querySelector('.carousel-arrow.left');const nextBtn=element.querySelector('.carousel-arrow.right');const updateCarousel=()=>{const currentItemsPerView=window.innerWidth<=480?1:window.innerWidth<=768?2:3;const translateX=-(currentIndex*(100/currentItemsPerView));carouselWrapper.style.transform=`translateX(${translateX}%)`;const items=element.querySelectorAll('.carousel-item');items.forEach((item,index)=>{item.classList.remove('center');const centerIndex=Math.floor(currentItemsPerView/2);if(index===currentIndex+centerIndex){item.classList.add('center')}})};prevBtn.addEventListener('click',()=>{if(currentIndex>0){currentIndex--;updateCarousel()}});nextBtn.addEventListener('click',()=>{const currentMaxIndex=Math.max(0,totalItems-(window.innerWidth<=480?1:window.innerWidth<=768?2:3));if(currentIndex<currentMaxIndex){currentIndex++;updateCarousel()}});window.addEventListener('resize',()=>{updateCarousel()});updateCarousel()}};BlogSyncComponent.initialize();</script>
#3. Edit page where you want to place Carousel > Add a Code Block > Paste this syntax into Code Block
<div data-sync-blog-url="/blog-01" data-style="carousel" data-limit="20"></div>
#4. Update Blog Page URL in the Code Block




