Featured images (thumbnails) are output with the_post_thumbnail(). Three things to get right: enabling it in the theme, specifying a size, and handling the case where none is set.
<?php the_post_thumbnail('large'); ?>1. First, enable it in the theme
If the “Featured image” panel isn’t in the editing screen, your theme doesn’t support it yet. Add one line to functions.php.
add_theme_support('post-thumbnails');For custom post types, include 'thumbnail' in supports when registering. Forget it and you end up with the panel on posts but not on products.
register_post_type('shohin', [
'supports' => ['title', 'editor', 'thumbnail'], // ← thumbnail
// …
]);Theme developmentCreating "products" with a custom post typeHow to register custom post types, in this lesson of the theme development course2. Specify a size
The first argument of the_post_thumbnail() is the size name. Leave it out and you get the small post-thumbnail size, so make specifying it a habit.
| Value | Meaning |
|---|---|
'thumbnail' | Thumbnail (150×150 by default, cropped) |
'medium' | Medium (300px wide by default) |
'large' | Large (1024px wide by default) |
'full' | The original uploaded size |
[600, 400] | Picks the closest thing to 600 wide by 400 tall |
You can change the numbers under “Settings” → “Media.” Note that WordPress picks from the sizes it has already generated, so lining up oversized full images in a list makes it heavy.
To add a class, pass an array as the second argument.
<?php the_post_thumbnail('medium', ['class' => 'card-image']); ?>3. Don’t let a missing image break the layout (fallbacks)
Featured images are sometimes just not there—and one missing image in an archive throws the whole look off. Branch on has_post_thumbnail().
<?php if (has_post_thumbnail()) : ?>
<?php the_post_thumbnail('medium', ['class' => 'card-image']); ?>
<?php else : ?>
<img class="card-image"
src="<?php echo esc_url(get_theme_file_uri('images/no-image.png')); ?>"
alt="" width="600" height="400">
<?php endif; ?>get_theme_file_uri() returns the URL of a file in your theme (the same idea as get_template_directory_uri() . '/images/no-image.png', but it handles child themes).
.card-image {
width: 100%;
aspect-ratio: 3 / 2;
object-fit: cover;
}When you just want the URL
For background images and OG tags, use the function that returns a URL.
<?php $url = get_the_post_thumbnail_url(get_the_ID(), 'large'); ?>
<?php if ($url) : ?>
<div class="hero" style="background-image: url('<?php echo esc_url($url); ?>');"></div>
<?php endif; ?>To output the featured image of a different post outside the loop, use the form that takes an ID: get_the_post_thumbnail($post_id, 'medium').
Making linked cards in an archive
<article class="card">
<a href="<?php the_permalink(); ?>">
<?php if (has_post_thumbnail()) : ?>
<?php the_post_thumbnail('medium', ['class' => 'card-image']); ?>
<?php endif; ?>
<h2><?php the_title(); ?></h2>
</a>
</article>Wrapping the image and title in a single link widens the clickable area and makes it easier to use.
Adding your own sizes
When the standard sizes don’t fit—“I want archive images cropped to 600×400”—add your own.
add_theme_support('post-thumbnails');
add_image_size('card', 600, 400, true); // fourth argument true = crop<?php the_post_thumbnail('card'); ?>- Fourth argument
true—crops to exactly that size (good for archive cards) - Fourth argument
false—scales down keeping the aspect ratio (nothing overflows, but heights vary)
Where does the alt attribute come from?
The alt attribute in the_post_thumbnail() comes from the “Alternative Text” you entered in the media library. Leave it empty and you get alt="".
- Ideally, make it a practice to enter descriptive text at upload time
- For decorative images,
alt=""is the right answer (it’s excluded from screen readers)
Using it for og:image
Featured images can also serve as the thumbnail when someone shares your page.
<?php
$og = is_singular() && has_post_thumbnail()
? get_the_post_thumbnail_url(get_the_ID(), 'large')
: get_theme_file_uri('images/og-default.png');
?>
<meta property="og:image" content="<?php echo esc_url($og); ?>">TipsSet up OGP (how it looks when shared)How OG tags work, and how to check themSummary
- When the panel is missing, use
add_theme_support('post-thumbnails'); for custom post types,'thumbnail'in supports - Always specify a size (
'medium','large'and so on).fullin an archive is heavy - Branch on
has_post_thumbnail()and show a fallback at the same aspect ratio - For just the URL,
get_the_post_thumbnail_url(). For your own sizes,add_image_size()(existing images need regenerating)
Images shape the impression an archive makes. Deciding “what happens when there isn’t one” keeps things from falling apart once the site is live.