WooCommerce recent products slider without a plugin

If you use WooCommerce as your eCommerce platform you’ll find there’s no shortage of plugins to enhance its functionality. But it’s good practice to install a plugin only when strictly necessary and if you’re using a WordPress theme that incorporates a modern framework like Bootstrap, a lightweight option is to recycle the code to make your own custom WooCommerce product slider.

The example below uses Bootstrap 5 carousel code and shows 12 products 3 at a time. If a product is marked out of stock it’s not selected. You can change the number of products shown by editing $slides, $products_per_slide and the Bootstrap column code.

recent products slider

<div id="recent-products" class="carousel slide" data-bs-ride="carousel">					
	
        <div class="carousel-inner">	

	<?php 
	$slides = 4;
	$products_per_slide = 3;
	
	$args = array(
	'post_type' => 'product',
	'orderby' => 'date',
	'posts_per_page' => $slides * $products_per_slide,
	'meta_query' => array(
		array(
			'key'     => '_stock_status',
			'value'   => 'outofstock',
			'compare' => '!='									
		)
	)
	
	);	
	
	$recent_products = new WP_Query( $args );	
	
	if ( $recent_products->have_posts() ) :
		$i = 0; 
		while ( $recent_products->have_posts() ) : $recent_products->the_post();
			if ( $i % $products_per_slide === 0 ) : ?>
				<div class="carousel-item <?php if ( $recent_products->current_post == 0 ) : ?>active<?php endif; ?>">
					<div class="row">
			<?php endif; ?>
						<div class="col-sm-4">
							<a href="<?php the_permalink() ?>"><?php echo woocommerce_get_product_thumbnail(); ?>
							<p class="mt-3 text-truncate text-truncate--2"><?php the_title(); ?></p></a>
						</div><!--/.col-sm-4 -->
			<?php if ( $i % $products_per_slide === $products_per_slide - 1 ) : ?>
					</div><!--/.row -->
				</div><!--/.carousel-item -->
			<?php endif; ?>
		<?php $i++; 
		endwhile;
		?>									
		<?php if ( $i % $products_per_slide !== 0 ) : ?>
					</div><!--/.row -->
				</div><!--/.carousel-item -->
		<?php endif; ?>								
	 <?php wp_reset_postdata(); endif; ?>
	</div><!--/.carousel-inner -->	
	
	<div class="carousel-controls">
		<a role="button" class="me-1 reverse-image" data-bs-target="#recent-products" data-bs-slide="prev"><svg xmlns="http://www.w3.org/2000/svg" width="22" height="22" viewBox="0 0 24 24"><path d="M12 2c5.514 0 10 4.486 10 10s-4.486 10-10 10-10-4.486-10-10 4.486-10 10-10zm0-2c-6.627 0-12 5.373-12 12s5.373 12 12 12 12-5.373 12-12-5.373-12-12-12zm2 12l-4.5 4.5 1.527 1.5 5.973-6-5.973-6-1.527 1.5 4.5 4.5z"/></svg><span class="visually-hidden">Previous</span>
		</a>
		<a role="button" class="ms-1" data-bs-target="#recent-products" data-bs-slide="next"><svg xmlns="http://www.w3.org/2000/svg" width="22" height="22" viewBox="0 0 24 24"><path d="M12 2c5.514 0 10 4.486 10 10s-4.486 10-10 10-10-4.486-10-10 4.486-10 10-10zm0-2c-6.627 0-12 5.373-12 12s5.373 12 12 12 12-5.373 12-12-5.373-12-12-12zm2 12l-4.5 4.5 1.527 1.5 5.973-6-5.973-6-1.527 1.5 4.5 4.5z"/></svg><span class="visually-hidden">Next</span>
		</a> 
	</div><!--/.carousel-controls -->
	
</div><!--/.carousel -->	
#recent-products .carousel-controls {
	position: absolute;
	right: 0;
	top: -46px;
}

#recent-products .reverse-image svg {
	 transform: scaleX(-1);
}