WordPress Read More Links

WordPress displays "Read More" links in two contexts: in excerpts (the_excerpt) and when using the tag in post content (the_content). You can customize both the text and appearance of these links to match your site's design and improve user engagement.

Benefits of Custom Read More Links

  • Better CTR: Custom text can increase click-through rates
  • Brand Voice: Match your site's tone and personality
  • User Clarity: Clear calls-to-action improve navigation
  • Accessibility: Descriptive text helps screen readers
  • Styling Control: Custom classes for design flexibility

Change Excerpt Read More Text

php
// Change "Read More" text in excerpts
function custom_excerpt_more($more) {
    return sprintf(
        ' %s',
        esc_url(get_permalink()),
        __('Continue Reading', 'textdomain')
    );
}
add_filter('excerpt_more', 'custom_excerpt_more');

Change Content More Link Text

php
// Change  link text
function custom_content_more_link($more_link, $more_link_text) {
    return sprintf(
        '%s',
        esc_url(get_permalink() . '#more-' . get_the_ID()),
        __('Read Full Article', 'textdomain')
    );
}
add_filter('the_content_more_link', 'custom_content_more_link', 10, 2);

Read More with Icon

php
function read_more_with_icon($more) {
    return sprintf(
        ' → %s',
        esc_url(get_permalink()),
        __('Keep Reading', 'textdomain')
    );
}
add_filter('excerpt_more', 'read_more_with_icon');

// CSS for icon styling
/* .read-more-link .icon {
    display: inline-block;
    margin-right: 5px;
    transition: transform 0.2s;
}
.read-more-link:hover .icon {
    transform: translateX(5px);
} */

Button-Styled Read More

php
function button_styled_read_more($more) {
    return sprintf(
        '%s',
        esc_url(get_permalink()),
        __('Read the Full Story', 'textdomain')
    );
}
add_filter('excerpt_more', 'button_styled_read_more');

// CSS for button
/* .read-more-wrapper {
    margin-top: 15px;
}
.read-more-btn {
    display: inline-block;
    padding: 10px 20px;
    background: #0066cc;
    color: white;
    text-decoration: none;
    border-radius: 4px;
    font-weight: 600;
    transition: background 0.3s;
}
.read-more-btn:hover {
    background: #0052a3;
} */

Read More with Post Title

php
function read_more_with_title($more) {
    return sprintf(
        ' %s "%s"',
        esc_url(get_permalink()),
        __('Continue reading', 'textdomain'),
        get_the_title()
    );
}
add_filter('excerpt_more', 'read_more_with_title');

Different Text for Different Post Types

php
function post_type_specific_read_more($more) {
    global $post;

    $read_more_text = array(
        'post'      => __('Read Article', 'textdomain'),
        'portfolio' => __('View Project', 'textdomain'),
        'product'   => __('View Product', 'textdomain'),
        'page'      => __('Learn More', 'textdomain')
    );

    $text = isset($read_more_text[$post->post_type])
        ? $read_more_text[$post->post_type]
        : __('Read More', 'textdomain');

    return sprintf(
        ' %s',
        esc_url(get_permalink()),
        $text
    );
}
add_filter('excerpt_more', 'post_type_specific_read_more');

Read More with Reading Time

php
function read_more_with_time($more) {
    // Calculate reading time (average 200 words per minute)
    $content = get_post_field('post_content', get_the_ID());
    $word_count = str_word_count(strip_tags($content));
    $reading_time = ceil($word_count / 200);

    return sprintf(
        ' %s (%d min read)',
        esc_url(get_permalink()),
        __('Continue Reading', 'textdomain'),
        $reading_time
    );
}
add_filter('excerpt_more', 'read_more_with_time');

Remove Read More Link Completely

php
// Remove excerpt more link
function remove_excerpt_more($more) {
    return '';
}
add_filter('excerpt_more', 'remove_excerpt_more');

// Remove content more link
function remove_content_more_link($more_link) {
    return '';
}
add_filter('the_content_more_link', 'remove_content_more_link');

Read More with Category-Specific Text

php
function category_specific_read_more($more) {
    if (has_category('tutorials')) {
        $text = __('View Tutorial', 'textdomain');
    } elseif (has_category('news')) {
        $text = __('Read News', 'textdomain');
    } elseif (has_category('reviews')) {
        $text = __('Read Review', 'textdomain');
    } else {
        $text = __('Read More', 'textdomain');
    }

    return sprintf(
        ' %s',
        esc_url(get_permalink()),
        $text
    );
}
add_filter('excerpt_more', 'category_specific_read_more');

Read More with Smooth Scroll

php
function read_more_smooth_scroll($more_link) {
    global $post;

    return sprintf(
        '%s',
        esc_url(get_permalink() . '#more-' . $post->ID),
        __('Continue Reading', 'textdomain')
    );
}
add_filter('the_content_more_link', 'read_more_smooth_scroll');

// JavaScript for smooth scrolling
/* 
document.querySelectorAll('.smooth-scroll').forEach(link => {
    link.addEventListener('click', function(e) {
        e.preventDefault();
        const targetId = this.getAttribute('href').split('#')[1];
        const target = document.getElementById(targetId);
        if (target) {
            target.scrollIntoView({ behavior: 'smooth', block: 'start' });
        }
    });
});
 */

Read More with SVG Icon

php
function read_more_with_svg($more) {
    $svg_arrow = '
        
    ';

    return sprintf(
        ' %s %s',
        esc_url(get_permalink()),
        __('Read More', 'textdomain'),
        $svg_arrow
    );
}
add_filter('excerpt_more', 'read_more_with_svg');

Read More in New Tab

php
function read_more_new_tab($more) {
    return sprintf(
        ' %s',
        esc_url(get_permalink()),
        __('Read More', 'textdomain')
    );
}
add_filter('excerpt_more', 'read_more_new_tab');

Advanced: Read More with Data Attributes

php
function read_more_with_data_attrs($more) {
    global $post;

    return sprintf(
        ' %s',
        esc_url(get_permalink()),
        $post->ID,
        $post->post_type,
        __('Read More', 'textdomain')
    );
}
add_filter('excerpt_more', 'read_more_with_data_attrs');

Template Tag for Manual Read More

php
// Create a reusable template tag
function custom_read_more_link($text = null, $class = 'read-more') {
    if ($text === null) {
        $text = __('Read More', 'textdomain');
    }

    return sprintf(
        '%s',
        esc_attr($class),
        esc_url(get_permalink()),
        esc_html($text)
    );
}

// Usage in templates:
// echo custom_read_more_link();
// echo custom_read_more_link('Continue Reading', 'btn btn-primary');

Complete Example with Multiple Styles

php
// Main read more customization function
function mytheme_read_more_link($more) {
    global $post;

    // Different styles for different contexts
    if (is_home() || is_archive()) {
        // Simple link for archives
        return sprintf(
            ' %s →',
            esc_url(get_permalink()),
            __('Continue Reading', 'textdomain')
        );
    } elseif (is_search()) {
        // Include post title in search results
        return sprintf(
            ' %s "%s"',
            esc_url(get_permalink()),
            __('Read', 'textdomain'),
            get_the_title()
        );
    } else {
        // Button style for other contexts
        return sprintf(
            '%s',
            esc_url(get_permalink()),
            __('Read Full Article', 'textdomain')
        );
    }
}
add_filter('excerpt_more', 'mytheme_read_more_link');

CSS Styling Examples

css
/* Basic Link Style */
.read-more-link {
    color: #0066cc;
    text-decoration: none;
    font-weight: 600;
    transition: color 0.2s;
}
.read-more-link:hover {
    color: #004499;
    text-decoration: underline;
}

/* Button Style */
.btn-read-more {
    display: inline-block;
    padding: 8px 16px;
    background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
    color: white;
    text-decoration: none;
    border-radius: 4px;
    font-weight: 600;
    transition: transform 0.2s, box-shadow 0.2s;
}
.btn-read-more:hover {
    transform: translateY(-2px);
    box-shadow: 0 4px 8px rgba(0,0,0,0.2);
}

/* Link with Arrow */
.read-more-link::after {
    content: "→";
    display: inline-block;
    margin-left: 5px;
    transition: transform 0.2s;
}
.read-more-link:hover::after {
    transform: translateX(5px);
}

/* Underline Effect */
.read-more-link {
    position: relative;
    padding-bottom: 2px;
}
.read-more-link::before {
    content: "";
    position: absolute;
    bottom: 0;
    left: 0;
    width: 0;
    height: 2px;
    background: #0066cc;
    transition: width 0.3s;
}
.read-more-link:hover::before {
    width: 100%;
}

Accessibility Considerations

php
// Accessible read more link with screen reader text
function accessible_read_more($more) {
    return sprintf(
        ' %s%s',
        esc_url(get_permalink()),
        sprintf(__('Continue reading %s', 'textdomain'), get_the_title()),
        __('Read More', 'textdomain')
    );
}
add_filter('excerpt_more', 'accessible_read_more');

// CSS for screen reader text
/* .screen-reader-text {
    position: absolute;
    width: 1px;
    height: 1px;
    padding: 0;
    margin: -1px;
    overflow: hidden;
    clip: rect(0,0,0,0);
    border: 0;
} */

Best Practices

Practice Why It Matters Example
Descriptive Text Better accessibility and SEO "Continue Reading Article Title" vs "Click Here"
Consistent Styling Professional appearance Use same class across all read more links
Clear CTA Higher click-through rates "Read Full Article" vs "More"
Escape Output Security Use esc_url(), esc_html()
Mobile-Friendly Touch targets Minimum 44x44px clickable area
Visual Feedback Better UX Hover states, transitions

Performance Impact

Zero performance impact. Customizing read more links is purely cosmetic and doesn't affect page load time or database queries. The filters execute during template rendering with negligible overhead.