In my previous post, Do You Need Yoast SEO, I explained why I chose Jetpack SEO over Yoast SEO as my primary SEO solution. Jetpack provides a strong SEO foundation on WordPress.com. Rather than relying on multiple plugins for fine-grained control, I prefer handling certain behaviors directly using lightweight PHP snippets.
This setup assumes your hosting plan allows custom PHP (for example, via the Code Snippets plugin) and that you’re comfortable managing small pieces of code. Please use the codes on your own responsibility.
Sitemap fine-tuning
By default, Jetpack generates a sitemap that includes media attachment URLs. From an SEO perspective, these pages rarely add value and can introduce thin or duplicate content into search results. Here is the PHP code to remove them
add_filter( 'jetpack_sitemap_image_skip_post', '__return_true' );add_filter( 'jetpack_sitemap_video_skip_post', '__return_true' );
Excluding specific pages from indexing
Not every automatically generated page deserves to be indexed.
For most blogs, date-based archive pages provide little unique value and can dilute a site’s structure. Preventing search engines from indexing them helps keep the focus on real content.
add_action('template_redirect', 'redirect_attachment_pages');// Noindex for date archives.add_action( 'wp_head', function() { if ( is_date() ) {?><meta name="robots" content="noindex,follow"> <?php }} );
Keeping post schema clean and consistent
Jetpack outputs a basic level of structured data to ensure technical compliance, but it doesn’t actively provide or optimize rich results.
You can test how your schema appears using Google’s Rich Results Test.
function add_optimized_post_schema() { if ( ! is_singular( 'post' ) ) { return; } $post_id = get_queried_object_id(); $post = get_post( $post_id ); if ( ! $post instanceof WP_Post ) { return; } $categories = get_the_category( $post_id ); $section = ! empty( $categories ) ? $categories[0]->name : ''; $tags = wp_get_post_terms( $post_id, 'post_tag', [ 'fields' => 'names' ] ); $image = null; if ( has_post_thumbnail( $post_id ) ) { $img = wp_get_attachment_image_src( get_post_thumbnail_id( $post_id ), 'full' ); if ( $img ) { $image = [ '@type' => 'ImageObject', 'url' => $img[0], 'width' => (int) $img[1], 'height' => (int) $img[2], ]; } } $desc = wp_strip_all_tags( get_the_excerpt( $post_id ) ); $schema = [ '@context' => 'https://schema.org', '@type' => 'BlogPosting', 'headline' => wp_strip_all_tags( get_the_title( $post_id ) ), 'datePublished' => get_the_date( 'c', $post_id ), 'dateModified' => get_the_modified_date( 'c', $post_id ), 'description' => $desc, 'articleSection' => $section, 'keywords' => ! empty( $tags ) ? implode( ', ', $tags ) : '', 'inLanguage' => get_bloginfo( 'language' ), 'author' => [ '@type' => 'Person', 'name' => get_the_author_meta( 'display_name', $post->post_author ), 'url' => get_author_posts_url( $post->post_author ), ], 'publisher' => [ '@type' => 'Organization', 'name' => 'Your Website Name', 'url' => home_url( '/' ), ], 'mainEntityOfPage' => [ '@type' => 'WebPage', '@id' => get_permalink( $post_id ), ], ]; if ( $image ) { $schema['image'] = $image; } echo '<script type="application/ld+json">' . wp_json_encode( $schema, JSON_UNESCAPED_SLASHES | JSON_UNESCAPED_UNICODE ) . '</script>';}add_action( 'wp_head', 'add_optimized_post_schema', 5 );
URL redirection (without a redirection plugin)
Content evolves, and URLs change. When that happens, unmanaged links can easily lead to 404 errors, which is never great for users or search engines. In my case, I renamed several blog categories and changed their slugs. Instead of relying on a dedicated redirection plugin, I handled this directly with PHP.
The approach was simple:
- Keep the old categories temporarily
- Move all posts to the new categories
- Redirect visits from the old category URLs to the new ones
- The old categories and the code can safely be removed after 6-12 months.
add_action( 'template_redirect', function () { if ( ! is_category() ) { return; } // Old category slug => New category slug $redirects = [ 'old-category' => 'new-category', 'old-category' => 'new-category', 'old-category' => 'new-category', ]; $category = get_queried_object(); if ( isset( $redirects[ $category->slug ] ) ) { $new_slug = $redirects[ $category->slug ]; // Prevent self-redirects (future-proof) if ( $category->slug === $new_slug ) { return; } $new_category = get_category_by_slug( $new_slug ); if ( $new_category && ! is_wp_error( $new_category ) ) { wp_redirect( get_category_link( $new_category->term_id ), 301 ); exit; } }});
Final thoughts
Jetpack SEO provides a solid foundation for WordPress sites, especially when combined with a few targeted PHP snippets.
The features I lost after removing Yoast were easily compensated for at the code level. Fine-tuning sitemaps, controlling indexing behavior, keeping schema consistent, and managing redirects with PHP keeps a WordPress.com site fast, clean, and search-engine friendly. Another plugin isn’t always the solution.
Have you tried handling SEO this way, or does it feel like an advanced topic to you?

Leave a Reply