8

I would like to disable all attachment pages completely. I Googled it, but there's just information on how to redirect to parent post or homepage. That's not what I would call an elegant solution. Why introduce unnecessary permalinks that redirect to the homepage? Couldn't it be disabled completely?

3
  • 1
    What do you mean by "disabled completely"? When adding media attachment URLs are created automatically. I don't know if you could disable this action without harming Wordpress core. Why isn't redirecting an elegant solution? What is the problem with the attachment URLs? I'm not judging, just trying to understand so I can offer a solution.
    – Fencer04
    Aug 31 '16 at 17:35
  • 2
    It just seems pointless to me that every file I upload gets its own page with a permalink. I can't think of many use scenarios for them. Most people just want to upload files to link to them, not creating a separate page to display them. Sep 1 '16 at 5:19
  • 1
    @Fencer04 it can be done without harming WP core, see my reply. In many cases it makes sense. Redirects are bad and technically it's not the proper use case for them - instead of redirecting existing URL you better don't have that URL in the first place if you don't use it. Also, on every request WP scans all rewrite rules array until finds the first match, it evaluates them using regular expressions, which is slow. Smaller array or rules means better performance. For this reason, I often remove dates, author archives, embeds, feeds etc - basically all features that aren't used on the project. Jun 23 '17 at 10:14
11

You can filter default rewrite rules and remove those for attachments:

function cleanup_default_rewrite_rules( $rules ) {
    foreach ( $rules as $regex => $query ) {
        if ( strpos( $regex, 'attachment' ) || strpos( $query, 'attachment' ) ) {
            unset( $rules[ $regex ] );
        }
    }

    return $rules;
}
add_filter( 'rewrite_rules_array', 'cleanup_default_rewrite_rules' );

Don't forget to re-save your permalinks once. WordPress will generate new rules without anything related to attachments.

Now, the attachment page URL gives 404. You can also add that redirect to prevent the 404 page, it's useless in this case. But I'm not sure how to catch the redirect - is_attachment() will not work if the rewrite rules are removed.

Update:

WordPress will still offer the attachment page pretty URLs in media library and media insertion dialog. You can filter this as well:

function cleanup_attachment_link( $link ) {
    return;
}
add_filter( 'attachment_link', 'cleanup_attachment_link' );

In this case, even when you insert your attachment into post ans select "Link to attachment page", the image will be inserted without the link.

5
  • Would it be possible to set the rewrite to be the media's File URL (linked to wp-content/uploads) instead of an auto-generated page? Jul 13 '17 at 17:25
  • Yes, I would like to have the possibility to redirect all attachment pages to the file url as well :)
    – Ola
    Oct 2 '18 at 9:21
  • The Yoast SEO plugin handles this perfectly. May 8 '20 at 13:01
  • By the way, this code does not work completely. If the attachment is loaded for a post or page, then everything works fine. If you just upload a attachment to the media library, its page still opens. May 8 '20 at 13:06
  • 2
    @Mario62RUS 1. Not everyone uses Yoast SEO. Some people do hate the bloat it brings. It's like cancer for your admin UI. 2. Yes, things have changed since 5.0 and Gutenberg. This code should be revised. May 11 '20 at 14:49
5

For those who might not use plugins or prefer light-weighted method. This might be of help.

This method redirect attachment to the exact file instead of the attachment page and it is the method that some plugins are using.

To test, by putting the following code in functions.php of the theme.

add_action( 'template_redirect', 'test_attachment_redirect', 10 );
function test_attachment_redirect() {
    if( is_attachment() ) {
        $url = wp_get_attachment_url( get_queried_object_id() );
        wp_redirect( $url, 301 );
    }
    return;
}

Reference: is_attachment wp_redirect

2

If you want to disable media pages completely, you should use a 404 response code instead of redirection. This can be done with the following code:

function wpse237762_set_404() {
    if (is_attachment()) {
        global $wp_query;
        $wp_query->set_404();
        status_header(404);
    }
}

// This will show 404 on the attachment page
add_filter('template_redirect', 'wpse237762_set_404');

// This will show 404 instead of redirecting to attachment page when dealing with a trailing slash
add_filter('redirect_canonical', 'wpse237762_set_404', 0);

To keep links to attachment pages working and redirect them straight to the file, you can use the following code:

function wpse237762_change_attachment_link($url, $id) {
    $attachment_url = wp_get_attachment_url($id);
    if ($attachment_url) {
        return $attachment_url;
    }
    return $url;
}

add_filter('attachment_link', 'wpse237762_change_attachment_link', 10, 2);

To prevent attachment pages from reserving slugs from normal pages, you can use this code to set all new attachment slugs to random ones (UUIDv4 in this case)

function wpse237762_unique_slug($slug, $post_ID, $post_status, $post_type, $post_parent, $original_slug) {
    if ($post_type === 'attachment') {
        return str_replace('-', '', wp_generate_uuid4());
    }
    return $slug;
}

add_filter('wp_unique_post_slug', 'wpse237762_unique_slug', 10, 6);

This will prevent an image named products.jpeg reserving the URL https://example.com/products. That would result in a page named Products being given the URL https://example.com/products-2 which obviously wouldn't be that great.

I have put this code together in the Disable Attachment Pages plugin, which also includes a tool to scramble existing attachment slugs so they won't cause any problems in the future.

Not the answer you're looking for? Browse other questions tagged or ask your own question.