Get The First Image From a Post

Let's say you wanted to use the post thumbnail feature of WordPress, but had a whole archive of posts that would take too much time to go through. For new posts, you can be specific and use the feature as intended. For old posts, you just want to use the first image it finds in the content for the thumbnail, or a default if none present.

Add this to functions.php or make a functionality plugin:

function catch_that_image() {
  global $post, $posts;
  $first_img = '';
  $output = preg_match_all('<img.+src=[\'"]([^\'"]+)[\'"].*>/i', $post->post_content, $matches);
  $first_img = $matches[1][0];

  if(empty($first_img)) {
    $first_img = "/path/to/default.png";
  return $first_img;

To use it, use this code in the loop:

if ( get_the_post_thumbnail($post_id) != '' ) {

  echo '<a href="'; the_permalink(); echo '" class="thumbnail-wrapper">';
  echo '</a>';

} else {

 echo '<a href="'; the_permalink(); echo '" class="thumbnail-wrapper">';
 echo '<img src="';
 echo catch_that_image();
 echo '" alt="" />';
 echo '</a>';


I found that has_post_thumbnail wasn't as reliable as the logic above.


  1. User Avatar
    Permalink to comment#

    Thanks for this. Always on the lookout to add functionality to WP.


  2. User Avatar
    Permalink to comment#

    Great function, I am trying to add youtube functionality to this but am a bit stuck.

    I wanted it to grab the youtube thumbnail if it sees a youtube embed before it sees an image. Any ideas?

    • User Avatar
      Robert Watcher
      Permalink to comment#

      I’m not familiar with how to make things work in WordPress – – – but I included similar functionality in my Journal which I recently rewrote (hand coded – not WordPress). It is based on my use of the iFrame Video Embed for HTML5 compatability in my Journal – so won’t work with object and embed code. Hopefully you can use it and adapt it to your WordPress application in a similar way as above with the first image.

      This video check code, comes after I have checked to see if there is an image in the content from a post (as I loop through). If it finds an iframe, it uses preg_match to extract the “src” of the iframe – and if there is a match to ‘’ – I can create a url based on the video id that is extracted from the src url.

      This is one of the pages that contains a couple of posts with Youtube video – where I got the Youtube images and display them –

      preg_match('|<iframe [^>]*(src="[^"]+")[^>]*|', $postcontent, $matches);
      $tmp_src = explode('/',$matches[1]);
      $vid_id = rtrim($tmp_src[count($tmp_src)-1], '"' );
      if($matches AND $tmp_src[2]==''){
      	$youtube_img_url = ''.$vid_id.'';
      	echo '<img src="'.$youtube_img_url.'" alt="You Tube Video" />';

      I have left out the extra if statements that check next for a Vimeo video url (which requries more complex code to extract) , as well as a default image if there is not a src url.

  3. User Avatar
    Permalink to comment#

    I have this in a page kind of like a small gallery but its limited due to:

    Settings >> Reading >> Blog pages show at most

    Is there a way around this to grab all images no matter what the limit is from settings?

  4. User Avatar
    Permalink to comment#

    I’ve been using the functions.php version of the code for a while now, but only recently discovered that this doesn’t seem to work for pages. Any chances there’s a way to make it apply to them as well?

  5. User Avatar
    zhen yi

    Hi, i would like to ask what if i want to get the second image instead of the first one? Helps are much appreciated thanks

  6. User Avatar
    Paul O'Flaherty

    That’s a great piece of code, thanks for sharing.

    I have a question though – if you were doing this from an attachment page (attachment.php) what would you change in the function to make it output correctly?



  7. User Avatar
    Carlos Goncalves

    How Can I change the image size?

    • User Avatar
      Permalink to comment#

      You should use some css:

      .thumbnail-wrapper img {width:300px;}

      If you want it to resize with the page use something like:

      .thumbnail-wrapper img {width:60%;}

  8. User Avatar
    Permalink to comment#

    Does anybody know how to get the first occurance of firstbigimage_big.jpg from:



  9. User Avatar
    Suwandi Halim
    Permalink to comment#

    Thanks. Help my day.

  10. User Avatar
    Permalink to comment#

    I found this high up in Google search, what a joke.

    Someone on should manage the snippets to not promote garbage code, preg matching the content for images tags..?..?

    WordPress already has a simple built in function for this called: get_children

    • User Avatar
      Chris Coyier
      Permalink to comment#

      For anyone reading this troll’s post and is worried about it…

      get_children gets images that are associated with the post. Like you used the built in image uploader to upload the image. That’s not always the case, hence needing to parse for it (e.g. an embedded flickr photo).

    • User Avatar
      Permalink to comment#

      @chris no, get_children() gets thumbnails associated to a post. This code extracts from post content the first img html tag.

    • User Avatar
      The Dro
      Permalink to comment#


  11. User Avatar
    Permalink to comment#

    Great tutorial. I would also like to know how to leverage this code to offer a dynamically sized image. It seems folks are using timthumb for this, I’m curious if there is a way to do it with core WP functions.

    It’s mentioned above that CSS can be used, but that’s not a great approach if you need to resize an image more than a few pixels. The goal is to deliver the image in a new size similar to how get_the_post_thumbnail($post->ID, array(80,80)); works. Thanks!

    • User Avatar
      Permalink to comment#

      I’d also love to know how to incorporate the built-in WP thumbnail sizes. Right now the code above pulls the image in it’s original dimensions, but I’d like it to crop a thumbnail using the dimensions I have specified in my functions.php.

      Any ideas?

    • User Avatar
      Nick Ciske


      You’d need to lookup the attachment ID using the URL then use that to get the image size you want:

    • User Avatar
      Permalink to comment#

      Did you ever find out how to do this? Its something I am struggling with .

    • User Avatar
      Hoa Si
      Permalink to comment#

      Here is the code I use to resize the first images:

       * Get the first image in a post. Strip Version. Retrieve the first image from each post and resize.
       * @param string $size get the first image size.
       * @link
       * see
       * Usage: Include in functions.php
       * <?php echo get_first_image('thumbnail'); ?> in the page template.
      function get_first_image( $size = 'thumbnail' ) {
          global $post, $posts;
          $first_img = '';
          preg_match_all( '<img.+src=[\'"]([^\'"]+)[\'"].*>/i', do_shortcode( $post->post_content, 'gallery' ), $matches );
            $first_img = isset( $matches[1][0] ) ? $matches[1][0] : null;
          if ( empty( $first_img ) ) {
                  return get_template_directory_uri() . '/assets/images/empty.png'; // path to default image.
          // Now we have the $first_img but we want the thumbnail of that image.
           $explode = explode( '.', $first_img );
           $count = count( $explode );
           $size = '-624x312'; // Our panel ratio (2:1) 312x156 for lighther page, 624x312 for retina; use add_image_size() and Force Regenerate Thumbnails plugin when changing sizes.
           $explode[ $count -2 ] = $explode[ $count -2 ] . '' . $size;
           $thumb_img = implode( '.', $explode );
           return $thumb_img;
          add_filter( 'get_first_image', 'thumbnail' );

      GitHubGist — get-first-image.php

  12. User Avatar
    Permalink to comment#

    Thank you so much! I don’t know why after all this time, I just don’t check your page first when it comes to WordPress.

  13. User Avatar
    Permalink to comment#

    I’d love to know how to use this logic in a child theme. I’ve hacked my child theme’s content.php so far to enable excerpts in the loop, but I’d really like the excerpt to show the first image in the post as well. Not got into making plugins yet, so I was hoping there might be a way, either by modifying my child theme’s content.php and/or its functions.php (crosses fingers) ;)

  14. User Avatar
    Permalink to comment#

    OMG I did it! Thanks TONS for this code!!!

  15. User Avatar
    Permalink to comment#

    This code is gold! It picks up the image if it’s a featured image or not. Brilliant! Thank you!!!

  16. User Avatar
    Permalink to comment#

    This is a great snippet, thanks for posting it.

    Just curious if anyone has successfully altered the function to return no IMG tag if no image is found instead of a placeholder? I’ve been tinkering with it but no joy, my PHP is rusty sadly.

    • User Avatar
      Permalink to comment#

      Remove these two lines from the function:

      if(empty($first_img)) {
      $first_img = “/path/to/default.png”;

      and then…

      if ( $image = catch_that_image() )
      echo '’;

  17. User Avatar
    Permalink to comment#

    great! what would be the code in order to show the LATEST image attached to a post. best, flo

  18. User Avatar
    Permalink to comment#

    For some reason this always gets the last image in a post and not the first. Used as is with a few posts with about 2 images in each.

    • User Avatar
      Permalink to comment#

      To get the first image instead of the last, replace /i with /U in the regular expression

  19. User Avatar
    Permalink to comment#

    @Barry – That’s strange – it’s taking the first image for me (i.e., the first image that appears in the post – the one nearest the top).

    I’m inserting the code inside a duplicated content.php in a child theme, directly after:


    div class=”entry-summary”>

    … in its own div.

    Seems to work for me.

  20. User Avatar
    Permalink to comment#

    Just one problem – it returns the first image for listings in the loop, but not for category listings

  21. User Avatar
    Permalink to comment#

    sorry – I meant, not for category listings where the first image is a featured image (I know I could get the first non-featured image, but I wondered if it could be tweaked to get the first featured image for category listings?

  22. User Avatar
    Permalink to comment#

    Ah – I worked it out – just to add:

    || is_category()

    … to the conditional.


  23. User Avatar
    Permalink to comment#

    Is there anyway we can display an image for Only First Post?

  24. User Avatar
    Permalink to comment#

    There’s a problem with the default image path when viewing category listings with pretty permalinks turned on – you get a broken image link because something like “images/default.jpg” is appended to the end of the permalink (e.g., “”).]

    Trying to think of a path to use that would cover all bases for that situation.

    • User Avatar
      The Dro
      Permalink to comment#

      add a / before images. This way you’re doing a direct path from the root.

  25. User Avatar

    I tried the code; it did return the image …

    p.s. I wrote my posts using windows live writer 2012 and embed Facebook photo link in live writer)

    But I couldn’t get the returned image in thumbnail size… Also, the image appears on top of the posts on both the index and individual post.

    That makes two images (one thumbnail and a duplicate one inside the post)..
    . I’d like to get rid of the thumbnail when it’s in single post while only showing the thumbnail with float left on index page.

    What can I do?

    I am using my own child theme from twenty twelve …

    Many thanks in advance…

  26. User Avatar

    Thanks! Works like a charm :)

  27. User Avatar
    Jordan Singleton

    This is how I handled it without regular expressions. I just put it in the template (in the loop of an archive page), but it wouldn’t be too hard to pull it into a function that could then be called in the template.

    <?php // Get thumbnail image
        if (has_post_thumbnail()) { 
        } else {
            $gallery_arguments = array(
            'post_type' => 'attachment',
            'post_mime_type' => 'image',
            'post_parent' => $post->ID,
            'numberposts' => 1);
            $gallery_images = get_children($gallery_arguments);
            if ($gallery_images) {
                foreach ($gallery_images as $post) {
                $image_attributes = wp_get_attachment_image_src($post->ID,'thumbnail');
                    <img src="<?php echo $image_attributes[0]; ?>">
            <?php } }
    • User Avatar

      I actually got to this page because I was doing something similar to what you have.

      I really liked that way, however get_children will only work if said image is only used in the current post. Or at least that’s where it was used first.
      That’s because in the current WP version, post_parent has to be unique (an attachment can’t have multiple parents).

      Solutions to this can however be obtained by hacking around with plugins that duplicate attachment entries in the database for each new post (see here).

      Are you using any of those solutions?

  28. User Avatar
    Archie Makuwa

    Hi guys,

    I am using a foundations theme and have followed the exact steps above. It works on the localhost (links to images in the right localhost path). The problem comes in on the live, the images path is that from the localhost:

    So basically it breaks. How to I turn the localhost url into a more dynamic one?

  29. User Avatar
    Dan Gaz
    Permalink to comment#

    Perfectly Working! :) Many ThanX

  30. User Avatar
    Permalink to comment#

    I’m currently give up with the_post_thumbnail(); function at all and moving to use first_img instead from duplicate my work making thumbnail and inside post image ..

  31. User Avatar
    Permalink to comment#

    I’ve been using this function for a while, now noticing that I’m getting a php notice in my error log, PHP Notice: Undefined offset: 0. for this line: $first_img = $matches [1] [0]; This post here: tells me I need to use isset() to check if something is in there first. Has anyone else experienced this? I’m only noticing this notice now, wondering what may have changed.

  32. User Avatar
    Permalink to comment#

    i have a problem the default img not show & it show me the error:

    Notice: Undefined offset: 0 in /vagrant/wp-content/themes/advocacy/functions.php on line 51

    line 51: $first_img = $matches[1][0];

    can someone help me?

    • User Avatar
      Permalink to comment#

      I found a solution that works for me:

      $output = preg_match_all(‘/<img.+src=\'”[\'”].*>/i’, $post->post_content, $matches);
      $first_img = $matches[1][0];


      if( $output = preg_match_all(‘/<img.+src=\'”[\'”].*>/i’, $post->post_content, $matches) )
      $first_img = $matches[1][0];

  33. User Avatar
    Permalink to comment#

    i am trying this.. but instead of getting image. i am getting only the link… can any one help me on this

  34. User Avatar
    Permalink to comment#

    This code looks very similar to an answer provided on StackOverflow.

  35. User Avatar
    Carol Ann
    Permalink to comment#


    I’m not a programmer, but think I have stumbled upon your post looking for the right thing and was hoping you could help me integrate your code into the following code in my theme?

    Thanks in advance :)

    if ( has_post_thumbnail() )  ?>
        <div class="entry-image" style="<?php echo $max_height; ?>">
            if(!of_get_option('post_image_lightbox')){ ?>
                <a href="<?php the_permalink(); ?>" title="<?php the_title(); ?>" rel="bookmark">
                    <?php the_post_thumbnail( $featured_image_size ); ?>
                $src = wp_get_attachment_image_src( get_post_thumbnail_id($post->ID), 'large', false, '' ); ?>
                <a href="<?php echo $src[0]; ?>" class="lightbox" title="<?php the_title(); ?>" rel="bookmark">
                    <?php the_post_thumbnail( $featured_image_size ); ?>
            } ?>
  36. User Avatar
    Permalink to comment#

    Is there a way to bypass the featured image and take the image that is listed first in the content? I’m using a child theme of twentythirteen and for some reason it will not crop my images when reducing it to thumbnail size. It just squeezes it into 100×100. So I’m forced to use a 100×100 image for my featured image (because I need a thumbnail displayed on my home page. I want to display the full size image on my page that displays my posts.

  37. User Avatar
    Permalink to comment#

    thanks a lot. It works. great helpful.

  38. User Avatar
    Permalink to comment#

    Hello sir please tell me how to use the second part of your code i mean how to add that code in a loop,sir i am a newbie so please help me thanks

  39. User Avatar
    Permalink to comment#

    This is great! Great fallback when no thumbnail is set. Thanks!

  40. User Avatar

    Hi there.
    Thank you for your code. I’ve used it to display 4-5 random posts along with their first image.
    The code works fine but I would like to get the images dynamically resized. Using CSS is not an option since the images on my website are quite big and therefore loading 4-5 full size images below each post would make the site slow.

    So, is there a dynamic way to resize the image?

    Thank you in advance for your help :)

  41. User Avatar

    Not working in custom post types .any one please provide a solution to this

  42. User Avatar

    hey guys,
    I was wondering , what would it be needed to make it retrieve more than just the first one. maybe the first 4 images…. ?

    I think the array must be modified but i don’t understand it much…

  43. User Avatar
    Kevin Hower

    First, thanks for this code! Second, I had the same undefined offset problem as some others had. So, what I did was leave the output line alone but change what came after that to :

    $first_img = $matches[1][0];
      if(empty($first_img)) {
        $first_img = "/path/to/default.png";
      return $first_img;

    in the function and then in my template i put this:

                &lt;a href=&quot;" &gt;
                  &lt;img src=&quot;" alt="" /&gt;

    I need to add some styling, but I’m still learning so I was more concerned with function for now than the style part. It also fixes the issue of having a default image show when there’s nothing to show, which was bugging me.

  44. User Avatar
    Kevin Hower

    Well, crud, this just isn’t my day apparently. I thought I had pasted my own code but apparenty I pasted the original .

    THIS is actually what I did in the function:

    if (!empty($matches[1][0]) ) {
    $first_img = $matches[1][0];
    } else {
    $first_img = “”;
    return $first_img;

    Sorry for any confusion.

  45. User Avatar
    Scott Fennell

    What’s the purpose of the $posts variable and output buffering? I tried it without either one and it worked fine. Here it is bundled up with an img tag and an alt attr:


    * Return an HTML img tag for the first image in a post content. Used to draw
    * the content for posts of the “image” format.
    * @return string An HTML img tag for the first image in a post content.
    function icicle_get_first_image() {

    // Expose information about the current post.
    global $post;
    // We'll trap to see if this stays empty later in the function.
    $src = '';
    // Grab all img src's in the post content
    $output = preg_match_all( '//i', $post-&gt;post_content, $matches );
    // Grab the first img src returned by our regex.
    if( ! isset ( $matches[1][0] ) ) { return false; }
    $src = $matches[1][0];
    // Sanitize for output
    $src = esc_url( $src );
    // Make sure there's still something worth outputting after sanitization.
    if( empty( $src ) ) { return false; }
    // Grab and sanitize the post title as an alt.
    $alt = esc_attr( $post-&gt;post_title );
    $out = "";
    return $out;


  46. User Avatar

    Hello, the code worked perfectly, however, I wonder how do I automatically generate a smaller image size, because it is loading the original image.

    I tried to do something like:

    add_image_size (‘thumb-medium’, 160, 140, true, array (‘center’, ‘top’));

    More unsuccessfully!

  47. User Avatar
    Permalink to comment#

    Hello, I want to show excerpt with first 300 characters of the post, how can I do it?

  48. User Avatar
    Permalink to comment#

    Thanks for this. work for me.

  49. User Avatar
    Permalink to comment#

    I tried this and it worked, but I have a problem with the fact that sometimes the first image turned out to be a smiley because it is also started with tag. Is there any way to exclude smilies from being selected as the first image?

    Tried to read about preg_match and regex but it’s way beyond my comprehension since I’m not a programmer myself.

  50. User Avatar
    Permalink to comment#

    Very helpful and works like a charm

  51. User Avatar
    Permalink to comment#

    Thanks so much for this tutorial and the one on Functionality plugin! I made my first plugin with the help of your tutorial and am so happy :)

    You and your site are the best!

  52. User Avatar
    Permalink to comment#

    That is an awesome hack. One quick question, how to get the thumbnail of the non-featured image displayed using catch_that_image()?

  53. User Avatar
    Permalink to comment#

    How do I make all thumbnails are aligned to the left?
    Thank you

  54. User Avatar
    Permalink to comment#

    First, thanks for the tip on the function! But, like someone above, I got “Undefined offset”. After many hours of trial and error I stumbled on this code:

    function catch_that_image() {
    global $post, $posts;
    $first_img = '';
    if(preg_match_all('<img.+src=[\'"]([^\'"]+)[\'"].*>/i', $post->post_content, $matches)){
    $first_img = $matches [1] [0];
    return $first_img;
    else {
    $first_img = get_template_directory_uri()."/images/default.jpg";
    return $first_img;

    This worked perfectly! Code from: Now, onto the next mission. Get this to only show the thumbnail of the caught image. God, I really need to learn php! ;)

    • User Avatar
      Permalink to comment#

      Almost a day later, after muuuch trial and errors and help from a lot of forum posts, I have come up with this:

      //Find first image in post
      function catch_that_image() {
      global $post, $posts, $wpdb;
      $first_img = '';
      if(preg_match_all('<img.+src=[\'"]([^\'"]+)[\'"].*>/i', $post->post_content, $matches)){
      $first_img = $matches [1] [0];
      // Get the upload directory paths
      $upload_dir_paths = wp_upload_dir();
      // If this is the URL of an auto-generated thumbnail, get the URL of the original image
      $attachment_url = preg_replace( '\d+x\d+(?=\.(jpg|jpeg|png|gif)$)/i', '', $first_img );
      // Remove the upload path base directory from the attachment URL
      $attachment_url = str_replace( $upload_dir_paths['baseurl'] . '/', '', $attachment_url );
       // Run a custom database query to get the attachment ID from the modified attachment URL
      $attachment_id = $wpdb->get_var( $wpdb->prepare( "SELECT wposts.ID FROM $wpdb->posts wposts, $wpdb->postmeta wpostmeta WHERE wposts.ID = wpostmeta.post_id AND wpostmeta.meta_key = '_wp_attached_file' AND wpostmeta.meta_value = '%s' AND wposts.post_type = 'attachment'", $attachment_url ) );
      $thumb_url = wp_get_attachment_image_src($attachment_id,'thumbnail', true);
      //Get thumbnail metadata
      $metadata = wp_get_attachment_metadata($attachment_id);
      $height =  $metadata['sizes']['thumbnail']['height'];
      $width =  $metadata['sizes']['thumbnail']['width'];
      $alt_text = get_post_meta($attachment_id, '_wp_attachment_image_alt', true);
      $title_text = get_the_title($attachment_id);
      //$caption_text = get_post($attachment_id)->post_excerpt;
      // Build the <img> string
      $Thumb_image = '<a href="' . get_permalink() . '">' .
      '<img src="' . $thumb_url[0] . '" width= "'. $width .'" height="'. $height .'" alt="'. $alt_text .'" title="'. $title_text .'" />' .
      // Echo the thumb image
      return $Thumb_image;
      //If no image found, return a default image
      else {
      $first_img = get_template_directory_uri() . '/img/Default.png';
      return '<img src="' . $first_img . '" alt="Alt text" title="Title text" />';

      It will find the first image, then find the corresponding thumbnail and add width, height, alt and title to the output. You can also add the caption. Uncomment the row “//$caption_text” and add the caption in in the image string.
      To use it:

      <?php echo catch_that_image(); ?>

      Hopefully this will save some time for someone else!

  55. User Avatar
    Surinder Kumar
    Permalink to comment#

    Thanks for this.

  56. User Avatar
    Permalink to comment#

    Thanks a lot, very usefull when working with content already in place that does not have featured images!

  57. User Avatar
    Permalink to comment#

    Thank you so much. Great post. Helped me a lot.

  58. User Avatar
    Permalink to comment#

    I was having problems with this code outputting the last image in the post, instead of the first. Not exactly sure why. But replacing the “preg_match_all” line with this, cured it.

    if(preg_match_all('/< *img[^>]*src *= *["\']?([^"\']*)/', $post->post_content, $matches)){

    Nice Code! Thanks.
    And thanks Richard for the version that delivers a sized thumbnail.

  59. User Avatar
    Permalink to comment#

    Does not work

    <link href="">
  60. User Avatar
    Permalink to comment#

    Thanks for the function.

  61. User Avatar
    Imran Bughio
    Permalink to comment#

    How can this be used to render custom image size?

  62. User Avatar
    sama web solutions
    Permalink to comment#

    Great functionality plugin :D

  63. User Avatar
    Michael Thompson
    Permalink to comment#

    I would strongly suggest wrapping $post->post_content in do_shortcode() so that you also grab images from galleries or other shortcodes that put images in content.

    Doing that, the output line looks like this:

    $output = preg_match_all('<img.+src=[\'"]([^\'"]+)[\'"].*>/i', do_shortcode($post->post_content), $matches);
  64. User Avatar

    Awesome! Thanks

  65. User Avatar

    Exactly what I was looking for and it works great! Thank you!

  66. User Avatar
    Permalink to comment#

    Worked great!!!!

Leave a Comment

Posting Code!

You may write comments in Markdown. This makes code easy to post, as you can write inline code like `<div>this</div>` or multiline blocks of code in triple backtick fences (```) with double new lines before and after.

Code of Conduct

Absolutely anyone is welcome to submit a comment here. But not all comments will be posted. Think of it like writing a letter to the editor. All submitted comments will be read, but not all published. Published comments will be on-topic, helpful, and further the discussion or debate.

Want to tell us something privately?

Feel free to use our contact form. That's a great place to let us know about typos or anything off-topic.