How to Customize the WordPress Excerpt (Length and “Read More” Link)

September 11, 2025
How to Customize the WordPress Excerpt (Length and “Read More” Link)

The excerpt is a short summary of your post used on blog archives, category pages, and widgets. You can control its length and the “read more” text (and even turn that into a link or button). This guide covers code-only ways that work in any classic or block theme.

1) Change the Global Excerpt Length

Add this to your theme’s functions.php (or a small site-specific plugin):

// Set excerpt length to 30 words (default ~55)
function my_excerpt_length( $length ) {
    return 30;
}
add_filter( 'excerpt_length', 'my_excerpt_length', 999 );

Per Post Type Length

// Different lengths by post type
function my_excerpt_length_by_type( $length ) {
    if ( is_admin() ) return $length;
    if ( is_post_type_archive( 'product' ) || get_post_type() === 'product' ) {
        return 15; // shorter for products
    }
    return 35; // default for blog
}
add_filter( 'excerpt_length', 'my_excerpt_length_by_type', 999 );

2) Customize the “Read More” Text (the ellipsis)

By default, WordPress adds [...] to auto-generated excerpts. Replace it globally:

// Replace [...] with a cleaner ellipsis
function my_excerpt_more( $more ) {
    return '…';
}
add_filter( 'excerpt_more', 'my_excerpt_more' );

3) Add a Linked “Read More” After Excerpts

Turn the ellipsis into a link to the single post:

// Add a linked "Read More" after auto-excerpts
function my_excerpt_more_link( $more ) {
    global $post;
    if ( is_admin() ) return $more;
    return '… <a class="read-more" href="' . get_permalink( $post ) . '">Read More</a>';
}
add_filter( 'excerpt_more', 'my_excerpt_more_link' );

Style the Link as a Button (optional)

.read-more {
  display: inline-block;
  padding: 0.5em 0.9em;
  border-radius: 4px;
  background: #0073aa;
  color: #fff;
  text-decoration: none;
}
.read-more:hover { background: #005177; }

4) Force a Custom Excerpt Length Only in Loops (Safe)

If you don’t want to change the global filter, trim per-template (e.g., in archive.php):

<?php
// Inside The Loop
$raw = get_the_excerpt(); // respects manual excerpts if set
echo wp_trim_words( $raw, 25, '… <a class="read-more" href="' . esc_url( get_permalink() ) . '">Read More</a>' );
?>

5) Respect Manual Excerpts (Best Practice)

If you write a manual excerpt in the editor, WordPress uses it. If not, it auto-generates from content. To always prefer manual but still customize fallback:

<?php
$manual = has_excerpt() ? get_the_excerpt() : '';
if ( $manual ) {
    echo wp_kses_post( $manual );
} else {
    echo wp_trim_words(
        wp_strip_all_tags( get_the_content() ),
        32,
        '… <a class="read-more" href="' . esc_url( get_permalink() ) . '">Read More</a>'
    );
}
?>

6) Add “Continue Reading” After the_content() Cut (“more” tag)

Note: The “more” tag (<!--more-->) affects the_content(), not excerpts. To unify the label:

// Change the_content more-link (when using <!--more-->)
function my_content_more_link( $link ) {
    return preg_replace( '/>.*?<\/a>/', '>Continue Reading</a>', $link );
}
add_filter( 'the_content_more_link', 'my_content_more_link' );

7) Add “Read Time” Before the Excerpt (nice UX)

// Helper: estimate read time (words ~200 wpm)
function my_estimated_read_time( $post_id = null ) {
    $content = get_post_field( 'post_content', $post_id ?: get_the_ID() );
    $words   = str_word_count( wp_strip_all_tags( $content ) );
    $mins    = max( 1, ceil( $words / 200 ) );
    return $mins . ' min read';
}
<?php
echo '<p class="read-time">' . esc_html( my_estimated_read_time() ) . '</p>';
the_excerpt(); // or your trimmed output
?>

8) Show Excerpts for Pages or Custom Post Types

Pages don’t show the excerpt box by default. Enable it:

// Allow excerpts on pages
add_post_type_support( 'page', 'excerpt' );

9) Use Excerpts in Block Themes

In the Site Editor, you can insert the Post Excerpt block and set its length in block settings. For finer control (link text, different lengths per template), still use the filters above; they apply regardless of theme type.

10) Common Patterns You Can Copy

A) Global: 26 words + linked “Read More”

add_filter( 'excerpt_length', function(){ return 26; }, 999 );
add_filter( 'excerpt_more', function( $more ){
    return '… <a class="read-more" href="' . esc_url( get_permalink() ) . '">Read More</a>';
});

B) Per-template: manual first, else 40 words + button

<?php
if ( has_excerpt() ) {
    the_excerpt();
} else {
    echo wp_trim_words(
        wp_strip_all_tags( get_the_content() ),
        40,
        '… <a class="read-more" href="' . esc_url( get_permalink() ) . '">Continue Reading</a>'
    );
}
?>

C) Per post type lengths

add_filter( 'excerpt_length', function( $l ){
    if ( get_post_type() === 'news' ) return 20;
    if ( get_post_type() === 'case_study' ) return 55;
    return 30;
}, 999 );

Troubleshooting

  • My theme ignores excerpt_length: Some themes hardcode their own trimming. Use the per-template wp_trim_words() approach to override.
  • HTML in excerpts looks broken: Auto-excerpts strip most HTML. For rich previews, build a custom snippet with wp_kses_post() and your own trimming.
  • Button duplicated: Ensure you don’t add a link via both the filter and your template.

Summary

  1. Use excerpt_length to set word count globally; vary by post type if needed.
  2. Use excerpt_more to customize the trailing text—turn it into a linked “Read More”.
  3. For full control, trim with wp_trim_words() in your templates and append a custom link.
  4. Prefer manual excerpts when you want editorial control; fall back to trimmed content.
  5. Style your “Read More” link as a button with simple CSS.
Avatar

Written by

satoshi

I’ve been building and customizing WordPress themes for over 10 years. In my free time, you’ll probably find me enjoying a good football match.