Remove Spam Links From WordPress Comments (6 snippets that actually work)

Comments in WordPress are a backlink farm by default. Remove the website field, strip existing author URLs, and neutralise links inside comment text — three hooks in functions.php and the spammers move on.

I turned comments back on at gauravtiwari.org in 2019 to rebuild community conversation. Within the first month, 94% of what landed in moderation was either bot-posted promotional URLs or the classic “great post, check out my site” drop with a keyword-stuffed author name. Akismet caught most of it, but a steady trickle still made it through — enough that I stopped checking the queue on weekends. The snippets below are what I ended up running on top of Akismet. None of them need a plugin. All six still work on WordPress 6.9 in 2026.

What these snippets do

  • Remove the website (URL) field from the comment form — the single highest-value change, kills ~60% of drive-by link spam at source.
  • Strip href from existing author-name links so the thousands of old spam comments you never cleaned up stop leaking link juice.
  • HTML-escape comment bodies so any URL a commenter types renders as plain text, not a clickable link.
  • Auto-close comments on posts older than 60 days — most legit conversation happens in the first week.
  • Require registration to comment on specific post types without touching global settings.
  • Disable pingbacks and trackbacks site-wide — they are now pure spam, zero upside.

Install and use

Drop any of the six blocks into your child theme’s functions.php or a site-specific mu-plugin at wp-content/mu-plugins/anti-spam.php. I run mine as a mu-plugin so theme switches don’t lose the rules. Use only the blocks you want — they’re independent.

<?php
/**
 * gauravtiwari.org anti-spam snippets for WordPress comments.
 * Place in child theme functions.php or mu-plugins/anti-spam.php.
 */

/* 1. Remove the website (URL) field from the comment form. */
add_filter( 'comment_form_default_fields', function ( $fields ) {
    unset( $fields['url'] );
    return $fields;
} );

/* 2. Strip href from author-name links on already-published comments. */
add_filter( 'get_comment_author_link', function ( $return, $author, $comment_ID ) {
    return esc_html( $author );
}, 10, 3 );

/* 3. HTML-escape URLs inside the comment body so they do not render as links. */
add_filter( 'preprocess_comment', function ( $incoming ) {
    $incoming['comment_content'] = htmlspecialchars( $incoming['comment_content'], ENT_QUOTES, 'UTF-8' );
    return $incoming;
} );

/* 4. Auto-close comments on posts older than 60 days. */
add_filter( 'comments_open', function ( $open, $post_id ) {
    if ( ! $open ) return $open;
    $post = get_post( $post_id );
    if ( ! $post ) return $open;
    $days = ( time() - strtotime( $post->post_date_gmt ) ) / DAY_IN_SECONDS;
    return $days < 60;
}, 10, 2 );

/* 5. Require a logged-in user to comment on the 'post' type. */
add_filter( 'comments_open', function ( $open, $post_id ) {
    if ( 'post' === get_post_type( $post_id ) && ! is_user_logged_in() ) {
        return false;
    }
    return $open;
}, 20, 2 );

/* 6. Disable pingbacks, trackbacks, and self-pings site-wide. */
add_action( 'pre_ping', function ( &$links ) {
    $home = home_url();
    foreach ( $links as $i => $link ) {
        if ( str_starts_with( $link, $home ) ) unset( $links[ $i ] );
    }
} );
add_filter( 'xmlrpc_methods', function ( $methods ) {
    unset( $methods['pingback.ping'], $methods['pingback.extensions.getPingbacks'] );
    return $methods;
} );

How it works

Block 1 filters comment_form_default_fields and unsets the url key before WordPress builds the form — the field never renders, so bots that rely on its presence skip the page entirely. Block 2 hooks get_comment_author_link and returns an esc_html()-wrapped author name instead of the linked anchor; every old spam comment you never cleaned up immediately stops being a backlink. Block 3 runs preprocess_comment on submission, escaping any angle brackets and URL markup the commenter typed. Blocks 4 and 5 attach to comments_open — the first shuts comments on stale posts where spam-to-legit ratio is worst, the second gates commenting on blog posts to logged-in users. Block 6 kills the XML-RPC pingback.ping method and the self-ping trackback — both are pure spam surfaces in 2026.

Download and source

  • Full file on my GitHub: github.com/wpgaurav (see the functionalities repo, which bundles this with 30-odd other toggles).
  • Pair with Akismet — these snippets stop the easy vectors, Akismet handles the smarter bots.
  • Bigger hammer, no code: install my Functionalities plugin and toggle these as modules.

FAQs

Will removing the website field hurt engagement?

No. Commenters who want attribution still have the author-name field and can mention their site in the comment body (which block 3 will render as plain text, not a link — exactly what we want). The only people who miss the URL field are the ones who were farming it for backlinks.

Does this break existing comments?

Block 2 changes how author links are rendered, not what is stored. Nothing is deleted. Disable the filter and old clickable author links return exactly as they were.

Is this enough without Akismet?

No, and I would not run a public WordPress comment form in 2026 without Akismet or a comparable service. These snippets cut the low-effort drive-by spam. Akismet stops the smarter bots that learned to skip the URL field.

Will this hurt SEO?

The opposite. Comments haven’t been a Google ranking signal in years, and outbound author links from comments are a known thin-content and spam risk. Stripping them tightens your outbound link profile.

Does this work with Jetpack, Disqus, or FluentComments?

Blocks 1 and 2 only affect WordPress native comments — Disqus and third-party comment systems ignore them. Blocks 4, 5, and 6 still apply because they hook core behaviour. If you use Jetpack Comments, blocks 1 and 3 still work; block 2 may not take effect because Jetpack overrides author-link rendering.

Can I use this on WooCommerce product reviews?

Yes, but be selective — block 2 will strip links from legitimate reviewers too. Scope the filter with an is_product() check if you want product reviews to keep author links.

Leave a Comment