WordPress the_excerpt without tags

Using the_excerpt without tags

Sooner or later, using the_excerpt raises a few common questions. For example, if a post begins with a heading or other markup like <strong> or <em>, those tags show up in the excerpt too — which often looks wrong. Beyond that, you may want to strip not just the tags but their content as well.

Problem: The default the_excerpt output may include unwanted HTML tags and heading markup. You may also need two distinct excerpts for the same post: one clean auto-generated preview for the page, and one manually written version for the <meta name="description"> tag.

Solution: Override the excerpt filter with a custom function that strips headings and inline tags. The trick is using '' == !$text (instead of the standard '' == $text) — this inverts the check so the auto-generation runs when the manual Excerpt field is filled in. The manual excerpt then serves as the meta description, while the function generates a clean preview from the post content. In a previous post we covered basic usage. Here's a function that handles everything at once, including custom word count and trailing text:

/* Output excerpt without tags or shortcodes */
add_filter( 'get_the_excerpt', 'custom_get_the_excerpt_helloadmin', 5 );

function custom_get_the_excerpt_helloadmin( $text ) {
    $raw_excerpt = $text;

    /*
     * Using '' == !$text (rather than '' == $text) enables two distinct excerpts:
     *   1. Auto-generated: first 40 words of post content, stripped of headings and tags.
     *   2. Manual: the "Excerpt" field on the Edit Post screen — ideal for meta description.
     * Note: if the manual Excerpt field is filled in, it takes precedence by default.
     */
    if ( '' == !$text ) {
        $text = get_the_content( '' );
        $text = strip_shortcodes( $text );
        $text = apply_filters( 'the_content', $text );
        $text = str_replace( ']]>', ']]>', $text );

        // Strip heading tags and their content
        $regex = '#(<h([1-6])[^>]*>)\s?(.*)?\s?(<\/h>)#';
        $text  = preg_replace( $regex, '', $text );

        $excerpt_length = apply_filters( 'excerpt_length', 40 );
        $excerpt_more   = apply_filters( 'excerpt_more', ' ...' );
        $excerpt        = wp_trim_words( $text, $excerpt_length, $excerpt_more );
    }

    return apply_filters( 'wp_trim_excerpt', $excerpt, $raw_excerpt );
}

NOTE: The filter priority is set to 5 so it runs before other excerpt filters. The heading regex removes the tag and its content entirely — not just the HTML wrapper — which prevents partial heading text from leaking into the excerpt. If you only need to strip HTML tags without removing heading content, wp_strip_all_tags() is simpler.