Skip to content

Early-bird lifetime licence: $199 once, for the first 200 buyers only. See the offer

Stop visitors from listing user names

Closes the usual ways to find your user names: ?author=1 links, the public users list in the REST API and the users sitemap. Logged-in editors still see authors as usual.

  • Type PHP
  • Runs Everywhere (runs as WordPress loads)
  • Tested with WordPress 7.1
PHP
<?php

// ?author=1 would redirect to /author/<user-name>/.
add_action(
	'template_redirect',
	static function () {
		// phpcs:ignore WordPress.Security.NonceVerification.Recommended -- Only checks that the parameter is there.
		if ( isset( $_GET['author'] ) && ! is_user_logged_in() ) {
			wp_safe_redirect( home_url( '/' ), 301 );
			exit;
		}
	},
	1
);

// /wp-json/wp/v2/users lists every author. Keep it for logged-in users (the
// block editor needs it) and hide it from everyone else.
add_filter(
	'rest_endpoints',
	static function ( $endpoints ) {
		if ( ! is_user_logged_in() ) {
			foreach ( array_keys( $endpoints ) as $route ) {
				if ( str_starts_with( $route, '/wp/v2/users' ) ) {
					unset( $endpoints[ $route ] );
				}
			}
		}
		return $endpoints;
	}
);

// No wp-sitemap-users-1.xml.
add_filter(
	'wp_sitemaps_add_provider',
	static fn( $provider, $name ) => 'users' === $name ? false : $provider,
	10,
	2
);

Good to know

Author archive pages (/author/name/) still work, so their addresses still show the author’s URL name. Give authors a display name that isn’t their login name.

In these packs

  • Harden WordPress: Close the doors attackers try first: XML-RPC, user name discovery, the file editors, revealing login errors.
  • Privacy and GDPR: Keep less personal data and send less of it to other companies.

Move your snippets over this afternoon.

Importing changes nothing until you switch over, and your old shortcodes keep working.