TikTok Embed Multiple Videos at Once - Complete Guide

TikTok Embed Multiple Videos at Once

Master bulk TikTok video embedding. Learn how to embed multiple TikTok videos simultaneously on your website with advanced grid layouts, carousels, and interactive galleries.

What is Bulk TikTok Video Embedding?

Bulk TikTok video embedding allows you to display multiple TikTok videos simultaneously on your website. This technique enables you to create engaging video galleries, showcase multiple content pieces, and provide users with a rich browsing experience without overwhelming your page performance.

By embedding multiple TikTok videos at once, you can create dynamic content sections, build video portfolios, and increase user engagement through diverse content presentation.

Key Benefits: Enhanced user engagement, better content organization, improved page performance, increased time on site, and better content discovery.

Multiple TikTok Video Embedding Methods

Method 1: TikTok Video Grid Layout

Create a responsive grid layout for multiple TikTok videos:

// TikTok Video Grid Layout
class TikTokVideoGrid {
  constructor(containerId, videos, options = {}) {
    this.container = document.getElementById(containerId);
    this.videos = videos;
    this.options = {
      columns: options.columns || 3,
      gap: options.gap || 20,
      aspectRatio: options.aspectRatio || '9:16',
      showCaptions: options.showCaptions || true,
      showUserInfo: options.showUserInfo || true,
      ...options
    };
    
    this.init();
  }

  init() {
    this.createGridLayout();
    this.bindEvents();
  }

  createGridLayout() {
    const gridHTML = `
      <div class="tiktok-video-grid" style="
        display: grid;
        grid-template-columns: repeat(${this.options.columns}, 1fr);
        gap: ${this.options.gap}px;
        padding: 20px;
      ">
        ${this.videos.map((video, index) => this.createVideoCard(video, index)).join('')}
      </div>
    `;
    
    this.container.innerHTML = gridHTML;
  }

  createVideoCard(video, index) {
    const [width, height] = this.options.aspectRatio.split(':').map(Number);
    const paddingTop = (height / width) * 100;
    
    return `
      <div class="tiktok-video-card" data-video-index="${index}">
        <div class="video-container" style="
          position: relative;
          padding-bottom: ${paddingTop}%;
          height: 0;
          overflow: hidden;
          border-radius: 12px;
          background: #000;
        ">
          <blockquote 
            class="tiktok-embed" 
            cite="${video.url}"
            data-video-id="${video.id}"
            style="
              position: absolute;
              top: 0;
              left: 0;
              width: 100%;
              height: 100%;
            ">
            <section></section>
          </blockquote>
        </div>
        
        ${this.options.showCaptions ? `
          <div class="video-caption">
            <p>${video.caption || 'TikTok Video'}</p>
          </div>
        ` : ''}
        
        ${this.options.showUserInfo ? `
          <div class="user-info">
            <span class="username">@${video.username}</span>
            <span class="likes">❤️ ${video.likes || 0}</span>
          </div>
        ` : ''}
      </div>
    `;
  }

  bindEvents() {
    // Load TikTok embed script
    if (!window.tiktok) {
      const script = document.createElement('script');
      script.src = 'https://www.tiktok.com/embed.js';
      script.async = true;
      document.head.appendChild(script);
    }

    // Add click events for video cards
    document.querySelectorAll('.tiktok-video-card').forEach((card, index) => {
      card.addEventListener('click', () => this.handleVideoClick(index));
    });
  }

  handleVideoClick(index) {
    const video = this.videos[index];
    console.log('Video clicked:', video);
    
    // Emit custom event for external handling
    const event = new CustomEvent('tiktokVideoClick', {
      detail: { video, index }
    });
    document.dispatchEvent(event);
  }

  // Update grid layout
  updateLayout(newOptions) {
    this.options = { ...this.options, ...newOptions };
    this.createGridLayout();
    this.bindEvents();
  }

  // Add new videos
  addVideos(newVideos) {
    this.videos = [...this.videos, ...newVideos];
    this.createGridLayout();
    this.bindEvents();
  }

  // Filter videos
  filterVideos(filterFn) {
    this.videos = this.videos.filter(filterFn);
    this.createGridLayout();
    this.bindEvents();
  }
}

// Usage Example
const tiktokVideos = [
  {
    id: 'video1',
    url: 'https://www.tiktok.com/@username/video/1234567890123456789',
    caption: 'Amazing dance moves! 💃',
    username: 'dancer123',
    likes: 1500
  },
  {
    id: 'video2',
    url: 'https://www.tiktok.com/@username/video/9876543210987654321',
    caption: 'Cooking tutorial 🍳',
    username: 'chef456',
    likes: 2300
  },
  {
    id: 'video3',
    url: 'https://www.tiktok.com/@username/video/5556667778889990001',
    caption: 'Travel adventures ✈️',
    username: 'traveler789',
    likes: 890
  }
];

const videoGrid = new TikTokVideoGrid('tiktok-grid-container', tiktokVideos, {
  columns: 3,
  gap: 20,
  aspectRatio: '9:16',
  showCaptions: true,
  showUserInfo: true
});

Method 2: TikTok Video Carousel

Create an interactive carousel for multiple TikTok videos:

// TikTok Video Carousel
class TikTokVideoCarousel {
  constructor(containerId, videos, options = {}) {
    this.container = document.getElementById(containerId);
    this.videos = videos;
    this.currentIndex = 0;
    this.options = {
      autoPlay: options.autoPlay || false,
      autoPlayInterval: options.autoPlayInterval || 5000,
      showNavigation: options.showNavigation || true,
      showIndicators: options.showIndicators || true,
      ...options
    };
    
    this.init();
  }

  init() {
    this.createCarouselHTML();
    this.bindEvents();
    this.showVideo(0);
    
    if (this.options.autoPlay) {
      this.startAutoPlay();
    }
  }

  createCarouselHTML() {
    const carouselHTML = `
      <div class="tiktok-video-carousel">
        <div class="carousel-container">
          <div class="video-slide active">
            <div class="video-wrapper">
              <blockquote class="tiktok-embed" cite="">
                <section></section>
              </blockquote>
            </div>
            <div class="video-info">
              <h3 class="video-title"></h3>
              <p class="video-caption"></p>
              <div class="user-info">
                <span class="username"></span>
                <span class="likes"></span>
              </div>
            </div>
          </div>
        </div>
        
        ${this.options.showNavigation ? `
          <button class="carousel-nav prev-btn">‹</button>
          <button class="carousel-nav next-btn">›</button>
        ` : ''}
        
        ${this.options.showIndicators ? `
          <div class="carousel-indicators">
            ${this.videos.map((_, index) => `
              <button class="indicator ${index === 0 ? 'active' : ''}" data-index="${index}"></button>
            `).join('')}
          </div>
        ` : ''}
      </div>
    `;
    
    this.container.innerHTML = carouselHTML;
  }

  showVideo(index) {
    const video = this.videos[index];
    const videoSlide = document.querySelector('.video-slide');
    const titleElement = document.querySelector('.video-title');
    const captionElement = document.querySelector('.video-caption');
    const usernameElement = document.querySelector('.username');
    const likesElement = document.querySelector('.likes');
    
    // Update video embed
    const videoWrapper = videoSlide.querySelector('.video-wrapper');
    videoWrapper.innerHTML = `
      <blockquote 
        class="tiktok-embed" 
        cite="${video.url}"
        data-video-id="${video.id}">
        <section></section>
      </blockquote>
    `;
    
    // Update video info
    titleElement.textContent = video.title || 'TikTok Video';
    captionElement.textContent = video.caption || '';
    usernameElement.textContent = '@' + video.username;
    likesElement.textContent = '❤️ ' + (video.likes || 0);
    
    // Update active states
    document.querySelectorAll('.video-slide').forEach(slide => slide.classList.remove('active'));
    videoSlide.classList.add('active');
    
    document.querySelectorAll('.indicator').forEach((indicator, i) => {
      indicator.classList.toggle('active', i === index);
    });
    
    this.currentIndex = index;
    
    // Load TikTok embed script if needed
    if (!window.tiktok) {
      const script = document.createElement('script');
      script.src = 'https://www.tiktok.com/embed.js';
      script.async = true;
      document.head.appendChild(script);
    }
  }

  nextVideo() {
    const nextIndex = (this.currentIndex + 1) % this.videos.length;
    this.showVideo(nextIndex);
  }

  prevVideo() {
    const prevIndex = this.currentIndex === 0 ? this.videos.length - 1 : this.currentIndex - 1;
    this.showVideo(prevIndex);
  }

  goToVideo(index) {
    if (index >= 0 && index < this.videos.length) {
      this.showVideo(index);
    }
  }

  bindEvents() {
    // Navigation buttons
    if (this.options.showNavigation) {
      document.querySelector('.prev-btn').addEventListener('click', () => this.prevVideo());
      document.querySelector('.next-btn').addEventListener('click', () => this.nextVideo());
    }

    // Indicators
    if (this.options.showIndicators) {
      document.querySelectorAll('.indicator').forEach((indicator, index) => {
        indicator.addEventListener('click', () => this.goToVideo(index));
      });
    }

    // Keyboard navigation
    document.addEventListener('keydown', (e) => {
      switch(e.code) {
        case 'ArrowLeft':
          this.prevVideo();
          break;
        case 'ArrowRight':
          this.nextVideo();
          break;
        case 'Space':
          e.preventDefault();
          this.toggleAutoPlay();
          break;
      }
    });

    // Touch/swipe support
    let startX = 0;
    let endX = 0;

    this.container.addEventListener('touchstart', (e) => {
      startX = e.touches[0].clientX;
    });

    this.container.addEventListener('touchend', (e) => {
      endX = e.changedTouches[0].clientX;
      this.handleSwipe(startX, endX);
    });
  }

  handleSwipe(startX, endX) {
    const swipeThreshold = 50;
    const diff = startX - endX;
    
    if (Math.abs(diff) > swipeThreshold) {
      if (diff > 0) {
        this.nextVideo(); // Swipe left
      } else {
        this.prevVideo(); // Swipe right
      }
    }
  }

  startAutoPlay() {
    this.autoPlayInterval = setInterval(() => {
      this.nextVideo();
    }, this.options.autoPlayInterval);
  }

  stopAutoPlay() {
    if (this.autoPlayInterval) {
      clearInterval(this.autoPlayInterval);
      this.autoPlayInterval = null;
    }
  }

  toggleAutoPlay() {
    if (this.autoPlayInterval) {
      this.stopAutoPlay();
    } else {
      this.startAutoPlay();
    }
  }
}

// Usage Example
const carouselVideos = [
  {
    id: 'carousel1',
    url: 'https://www.tiktok.com/@user1/video/1111111111111111111',
    title: 'Dance Challenge',
    caption: 'Join the challenge! 💃',
    username: 'user1',
    likes: 2500
  },
  {
    id: 'carousel2',
    url: 'https://www.tiktok.com/@user2/video/2222222222222222222',
    title: 'Recipe Tutorial',
    caption: 'Easy 5-minute recipe 🍳',
    username: 'user2',
    likes: 1800
  }
];

const videoCarousel = new TikTokVideoCarousel('carousel-container', carouselVideos, {
  autoPlay: true,
  autoPlayInterval: 8000,
  showNavigation: true,
  showIndicators: true
});

Advanced TikTok Video Gallery

Masonry Layout Gallery

Create a Pinterest-style masonry layout for TikTok videos:

// TikTok Masonry Gallery
class TikTokMasonryGallery {
  constructor(containerId, videos, options = {}) {
    this.container = document.getElementById(containerId);
    this.videos = videos;
    this.options = {
      columns: options.columns || 4,
      gap: options.gap || 15,
      showFilters: options.showFilters || true,
      showSearch: options.showSearch || true,
      ...options
    };
    
    this.filteredVideos = [...this.videos];
    this.init();
  }

  init() {
    this.createGalleryHTML();
    this.bindEvents();
    this.renderVideos();
  }

  createGalleryHTML() {
    const galleryHTML = `
      <div class="tiktok-masonry-gallery">
        ${this.options.showSearch ? `
          <div class="search-container">
            <input type="text" class="search-input" placeholder="Search videos...">
          </div>
        ` : ''}
        
        ${this.options.showFilters ? `
          <div class="filter-container">
            <button class="filter-btn active" data-filter="all">All</button>
            <button class="filter-btn" data-filter="dance">Dance</button>
            <button class="filter-btn" data-filter="comedy">Comedy</button>
            <button class="filter-btn" data-filter="food">Food</button>
            <button class="filter-btn" data-filter="travel">Travel</button>
          </div>
        ` : ''}
        
        <div class="masonry-container"></div>
      </div>
    `;
    
    this.container.innerHTML = galleryHTML;
  }

  renderVideos() {
    const masonryContainer = document.querySelector('.masonry-container');
    const videoHTML = this.filteredVideos.map(video => this.createVideoItem(video)).join('');
    
    masonryContainer.innerHTML = videoHTML;
    
    // Initialize masonry layout
    this.initMasonry();
  }

  createVideoItem(video) {
    return `
      <div class="masonry-item" data-category="${video.category || 'general'}">
        <div class="video-card">
          <div class="video-thumbnail">
            <img src="${video.thumbnail || 'https://via.placeholder.com/300x400'}" alt="${video.caption}">
            <div class="play-overlay">▶</div>
          </div>
          <div class="video-details">
            <p class="video-caption">${video.caption}</p>
            <div class="video-meta">
              <span class="username">@${video.username}</span>
              <span class="likes">❤️ ${video.likes}</span>
            </div>
          </div>
        </div>
      </div>
    `;
  }

  initMasonry() {
    const container = document.querySelector('.masonry-container');
    const items = container.querySelectorAll('.masonry-item');
    
    // Simple masonry implementation
    let columns = this.options.columns;
    let columnHeights = new Array(columns).fill(0);
    
    items.forEach((item, index) => {
      const columnIndex = index % columns;
      const left = columnIndex * (100 / columns);
      
      item.style.position = 'absolute';
      item.style.left = left + '%';
      item.style.top = columnHeights[columnIndex] + 'px';
      
      // Update column height
      columnHeights[columnIndex] += item.offsetHeight + this.options.gap;
    });
    
    // Set container height
    const maxHeight = Math.max(...columnHeights);
    container.style.height = maxHeight + 'px';
  }

  filterVideos(category) {
    if (category === 'all') {
      this.filteredVideos = [...this.videos];
    } else {
      this.filteredVideos = this.videos.filter(video => 
        video.category === category
      );
    }
    
    this.renderVideos();
  }

  searchVideos(query) {
    if (!query.trim()) {
      this.filteredVideos = [...this.videos];
    } else {
      this.filteredVideos = this.videos.filter(video =>
        video.caption.toLowerCase().includes(query.toLowerCase()) ||
        video.username.toLowerCase().includes(query.toLowerCase())
      );
    }
    
    this.renderVideos();
  }

  bindEvents() {
    // Filter buttons
    if (this.options.showFilters) {
      document.querySelectorAll('.filter-btn').forEach(btn => {
        btn.addEventListener('click', (e) => {
          document.querySelectorAll('.filter-btn').forEach(b => b.classList.remove('active'));
          e.target.classList.add('active');
          this.filterVideos(e.target.dataset.filter);
        });
      });
    }

    // Search input
    if (this.options.showSearch) {
      const searchInput = document.querySelector('.search-input');
      searchInput.addEventListener('input', (e) => {
        this.searchVideos(e.target.value);
      });
    }

    // Video card clicks
    document.addEventListener('click', (e) => {
      if (e.target.closest('.video-card')) {
        const videoCard = e.target.closest('.video-card');
        const videoIndex = Array.from(videoCard.parentElement.parentElement.children).indexOf(videoCard.parentElement);
        const video = this.filteredVideos[videoIndex];
        this.openVideoModal(video);
      }
    });
  }

  openVideoModal(video) {
    const modalHTML = `
      <div class="video-modal">
        <div class="modal-content">
          <span class="close-btn">&times;</span>
          <div class="video-container">
            <blockquote 
              class="tiktok-embed" 
              cite="${video.url}"
              data-video-id="${video.id}">
              <section></section>
            </blockquote>
          </div>
          <div class="video-info">
            <h3>${video.caption}</h3>
            <p>@${video.username}</p>
            <span>❤️ ${video.likes}</span>
          </div>
        </div>
      </div>
    `;
    
    document.body.insertAdjacentHTML('beforeend', modalHTML);
    
    // Load TikTok embed script
    if (!window.tiktok) {
      const script = document.createElement('script');
      script.src = 'https://www.tiktok.com/embed.js';
      script.async = true;
      document.head.appendChild(script);
    }
    
    // Close modal functionality
    document.querySelector('.close-btn').addEventListener('click', () => {
      document.querySelector('.video-modal').remove();
    });
    
    document.querySelector('.video-modal').addEventListener('click', (e) => {
      if (e.target.classList.contains('video-modal')) {
        e.target.remove();
      }
    });
  }
}

// Usage Example
const galleryVideos = [
  {
    id: 'gallery1',
    url: 'https://www.tiktok.com/@user1/video/1111111111111111111',
    caption: 'Amazing dance moves!',
    username: 'user1',
    likes: 1500,
    category: 'dance',
    thumbnail: 'https://example.com/thumb1.jpg'
  },
  {
    id: 'gallery2',
    url: 'https://www.tiktok.com/@user2/video/2222222222222222222',
    caption: 'Funny comedy skit',
    username: 'user2',
    likes: 2300,
    category: 'comedy',
    thumbnail: 'https://example.com/thumb2.jpg'
  }
];

const masonryGallery = new TikTokMasonryGallery('gallery-container', galleryVideos, {
  columns: 4,
  gap: 15,
  showFilters: true,
  showSearch: true
});

Multiple TikTok Video Embedding Best Practices

Performance Optimization

  • • Implement lazy loading for videos
  • • Use appropriate grid layouts
  • • Limit initial video count
  • • Optimize thumbnail images

User Experience

  • • Add loading states
  • • Implement smooth transitions
  • • Provide navigation controls
  • • Ensure mobile responsiveness

Content Organization

  • • Group videos by category
  • • Implement search functionality
  • • Use consistent thumbnails
  • • Maintain content hierarchy

Technical Implementation

  • • Handle API rate limits
  • • Implement error handling
  • • Use responsive design
  • • Test across devices

Ready to Create Multiple TikTok Video Embeds?

Transform your website with dynamic TikTok video galleries. Use our iframe generator tool to create stunning multiple video embeds that will engage your visitors.

Create TikTok Video Gallery