How to create a “Recent Post” carousel using Owl Carousel

Scott Taylor's Layout avatar

As most of you know, WordPress comes with a “Recent Posts” widget that will pull the titles of your most recent posts into a sidebar and link them to the full post. The problem with this is that the Recent Posts widget is very limiting. What if you need something a little more elegant and with a little more functionality? For example, what if you want to pull in the Featured Image and an excerpt, and from a custom post type? There are definitely some plugins out there that will do these things, such as Advanced Recent Posts or Recent Posts Widget Extended. In fact, there are a lot of great plugins out there for displaying posts and some will even allow you to style them to match your theme.

However, querying posts is actually a pretty easy thing to do and going the DIY route will almost always guarantee that you get exactly what you want and that your carousel will be styled to match your theme perfectly.

In this article, I will show you how to build a “Recent Posts” carousel using the popular Owl Carousel JavaScript library.

Let’s get started. If you are reviewing the examples on the Owl Carousel site, the first thing you will notice is that their examples are written for a plain HTML site. In order to get Owl Carousel working in WordPress, you will have to do things slightly differently.

First, you need to download the files from the Owl Carousel site or fork them from Github. Once you have the files locally, you will want to add the main CSS file to your theme’s /css/ directory. That file is owl.carousel.min.css. There is another CSS file in there for a theme and it is owl.theme.default.min.css. It isn’t a required file, therefore, I’m not going to use it in this tutorial.

Remember: You should never make changes on a live site. Our free local development app, Local, will help you simplify your workflow and safely experiment with your site. Try it today!

Once uploaded to your theme, the path to the file should look something like this:

You also need to include the JS files

If your child theme doesn’t already have a /js/ folder, go ahead and create one now. Then, add the owl.carousel.min.js to your theme’s /js/ directory so that it looks something like the following: /wp-content/themes/your-theme/js/owl.carousel.min.js.

Next, you need to add some jQuery that initializes and controls your carousel

This code will configure your specific needs of the carousel. If you don’t already have a JS file that controls other script configurations, create a settings.js file and put it in the same /js/ directory as above. That should look something like: /wp-content/themes/your-theme/js/settings.js.

Next, you’ll add the following code to that same JavaScript file and save. This code is what makes the call to the carousel and tells it how many items to use, whether or not to loop, what kind of navigation to use, and how to respond to different device sizes.

Note: For this tutorial, I’m also using Font Awesome to supply the arrow icons on the carousel. To learn more about Font Awesome, check out this article.

(function($) {
"use strict";

$(document).ready(function() {

$('#blog .owl-carousel').owlCarousel({
dots: false,
nav: true,
navText: ['<i class="fa fa-arrow-left fa-2x"></i>','<i class="fa fa-arrow-right fa-2x"></i>'], //Note, if you are not using Font Awesome in your theme, you can change this to Previous & Next

You will need to register and enqueue any new files added. If you already had a settings.js or custom.js, it should already be enqueued in your theme. However, because you are adding at least two new files (owl.carousel.min.css and owl.carousel.min.js), you will need to open your theme’s functions.php and properly add them to your theme. It should look something like this:

add_action( 'wp_enqueue_scripts', 'yourtheme_scripts');
function yourtheme_scripts(){
wp_enqueue_script('owl.carousel', get_template_directory_uri() . '/js/owl.carousel.min.js', array(), '1.0.0', true );
wp_enqueue_script('settings', get_template_directory_uri() . '/js/settings.js', array(), '1.0.0', true );

function yourtheme_styles() {
wp_register_style('owl-carousel', get_template_directory_uri() .'/css/owl.carousel.css', array(), null, 'all' );
wp_enqueue_style( 'owl-carousel' );
add_action( 'wp_enqueue_scripts', 'yourtheme_styles' );

The HTML and PHP that will display the carousel on your page

This section can vary depending on how your theme is set up and where you want to put the carousel. I am going to be using a custom template that I built using Bootstrap. Your first step here is to determine where you want the carousel to show up. If you want it to be on your homepage, you should look for home.php or frontpage.php. The name varies from theme to theme, so make sure you understand your theme’s structure and edit the right file. Once you know what file to edit, you should make a copy of it in your child theme and make sure it resides in the the same directory structure. For example, if the file resides in a directory called templates, make sure you create a folder called templates in the same location as your parent theme.

Once you are ready to go, you can add the following in the appropriate location. In my file, I added this to the bottom of my frontpage.php so that it displays just above the footer of my site.

<!-- ============ BLOG CAROUSEL START ============ -->
<section id="blog">
  <div class="container">
     <div class="row"> <!-- this is the carousel’s header row -->
        <div class="col-sm-12 text-center">
           <h5>Recent posts</h5>
     <div class="row"> <!-- this row starts the carousel-->
        <div class="col-sm-12">
           <div class="owl-carousel">
              <!-- query the posts to be displayed -->
              <?php $loop = new WP_Query(array('post_type' => 'post', 'posts_per_page' => -1, 'orderby'=> 'ASC')); //Note, you can change the post_type to a CPT and set the number to pull and order to display them in here. ?>
              <?php while ( $loop->have_posts() ) : $loop->the_post(); ?>
                 <div class="recent-post"> <!-- I don’t have any unique css here, just needed to make sure every recent post gets wrapped as a block element.  However, you may want to add your own css here... -->
<a href="<?php print get_permalink($post->ID) ?>">
              <?php echo the_post_thumbnail(); ?></a>
              <h4><?php print get_the_title(); ?></h4>
              <?php print get_the_excerpt(); ?><br />
          <p><a class="btn btn-default" href="<?php print get_permalink($post->ID) ?>">More</a></p>
</div> <!-- End the Recent Post div -->
              <?php endwhile; ?>
           </div> <!-- End the Owl Carousel div -->
        </div> <!-- End the recent posts carousel row -->
        <div class="row"> <!-- start of new row for the link to the blog -->
           <div class="col-sm-12 text-center">
              <a href="blog.html" class="btn btn-primary">Read All Posts</a>
     </div> <!-- End blog button row -->
</section>  <!-- ============ RECENT POSTS CAROUSEL END ============ -->

When you are finished, you should have a carousel that shows the post’s featured image, title, excerpt, and a “More” button that links you to the full blog post.

Comments (9 )

  1. Mollie

    May 27, 2016

    The links to Owl are broken.

  2. Schalk

    June 28, 2016


    I added your code into template-parts/content.php ( Im using my own fork from _s underscores theme )

    If I added it directly to my index, it seems to work, but then place it where i want ( with content before and after )

    Any ideas?

    • Schalk

      June 28, 2016

      ... issue with my footer.php. all sorted, thank you!

  3. Rachael Portier

    October 12, 2016

    I've literally tried everything to get this to work, but all it displays is the posts in a list format. I'm guessing it has something to do with the jQuery, any ideas?

    • Dea

      October 20, 2016

      Same problem as Rachel.

  4. Duncan

    October 22, 2016

    Unfortunatly this doesn't work, it just shows a list of posts and doesn't trigger Owl styling.

    Also you have a stray '<?php' in your code.

    Do you have any update on this? I am sure would help a lot of folks :)

  5. Maira

    October 25, 2016

    I've used this inside a function (I use Genesis) and it works fine:


    'post', 'posts_per_page' => -1, 'orderby'=> 'ASC'));?>
    have_posts() ) : $loop->the_post(); ?>

    <a href="ID) ?>">


    Also, added a custom image size called 'slider'.

  6. Raju

    November 12, 2016

    Hey Scott,

    Thanks man, it's working for me.

  7. Zanderjaz

    September 22, 2017

    Worked great for me, but I'm not a total noob. Thanks.

    I'm using custom styles on mine, but If anyone is having trouble with CSS styles not appearing, be sure to enqueue the styles from the carousel download package (I'd recommend pasting them into your main style.css file as to not load up another unnecessary HTTP request), and also be sure your theme is running the latest version of jQuery.

    Finally, I'd also like to note the code on this page breaks themes due a stray '<?php' opening tag before the permalink line. Everything rendering after this stray PHP opening tag will break on the page.

    <a href="ID) ?>">

  8. طراحی سایت در کرج

    February 21, 2019

    hi scott , how can i use post number from category for sample, 4 post from custom category
    thanks :)

  9. Ajay Radadiya

    June 24, 2019

    Post slider wordpress this also most beautiful plugin in wordpress for WordPress Slider & Carousel

Join the discussion