Commit 16a09dd4e19 for woocommerce
commit 16a09dd4e197e0fef088d0d5d8093518ee74b8e6
Author: Tung Du <dinhtungdu@gmail.com>
Date: Mon Aug 31 13:23:14 2026 +0700
Fix canonical product archive pagination links (#68116)
* fix: use canonical product pagination links
* Add changelog entry for pagination fix
diff --git a/plugins/woocommerce/changelog/fix-canonical-product-pagination b/plugins/woocommerce/changelog/fix-canonical-product-pagination
new file mode 100644
index 00000000000..ca5859d383f
--- /dev/null
+++ b/plugins/woocommerce/changelog/fix-canonical-product-pagination
@@ -0,0 +1,4 @@
+Significance: patch
+Type: fix
+
+Fix product archive pagination links to the first page.
diff --git a/plugins/woocommerce/includes/wc-template-functions.php b/plugins/woocommerce/includes/wc-template-functions.php
index 9a1350c3be6..0dd33771932 100644
--- a/plugins/woocommerce/includes/wc-template-functions.php
+++ b/plugins/woocommerce/includes/wc-template-functions.php
@@ -1777,8 +1777,21 @@ if ( ! function_exists( 'woocommerce_pagination' ) ) {
);
if ( ! wc_get_loop_prop( 'is_shortcode' ) ) {
- $args['format'] = '';
- $args['base'] = esc_url_raw( str_replace( 999999999, '%#%', remove_query_arg( 'add-to-cart', get_pagenum_link( 999999999, false ) ) ) );
+ global $wp_rewrite;
+
+ $args['base'] = esc_url_raw( str_replace( 999999999, '%#%', remove_query_arg( 'add-to-cart', get_pagenum_link( 999999999, false ) ) ) );
+
+ if ( $wp_rewrite->using_permalinks() ) {
+ $args['format'] = user_trailingslashit( $wp_rewrite->pagination_base . '/%#%', 'paged' );
+
+ if ( ! $wp_rewrite->use_trailing_slashes ) {
+ $args['format'] = '/' . ltrim( $args['format'], '/' );
+ }
+ } else {
+ $args['format'] = false !== strpos( $args['base'], '?paged=%#%' ) ? '?paged=%#%' : '&paged=%#%';
+ }
+
+ $args['base'] = str_replace( $args['format'], '%_%', $args['base'] );
}
wc_get_template( 'loop/pagination.php', $args );
diff --git a/plugins/woocommerce/tests/php/includes/wc-template-functions-test.php b/plugins/woocommerce/tests/php/includes/wc-template-functions-test.php
index 4719fbc1473..6657301ff7c 100644
--- a/plugins/woocommerce/tests/php/includes/wc-template-functions-test.php
+++ b/plugins/woocommerce/tests/php/includes/wc-template-functions-test.php
@@ -224,4 +224,58 @@ class WC_Template_Functions_Tests extends \WC_Unit_Test_Case {
$this->assertStringContainsString( 'rel="nofollow"', $markup );
}
+
+ /**
+ * @testdox Pagination defaults link page one to the canonical archive URL.
+ */
+ public function test_pagination_defaults_link_page_one_to_canonical_archive_url(): void {
+ global $wp_rewrite;
+
+ $original_permalink_structure = $wp_rewrite->permalink_structure;
+ $buffer_level = ob_get_level();
+ $previous_loop = $GLOBALS['woocommerce_loop'] ?? null;
+ $pagination_args = null;
+ $get_pagenum_link_filter = static function ( $link, $pagenum ) {
+ return 'https://example.test/shop/page/' . $pagenum . '/';
+ };
+ $pagination_args_filter = static function ( $args ) use ( &$pagination_args ) {
+ $pagination_args = $args;
+ return $args;
+ };
+
+ $wp_rewrite->set_permalink_structure( '/%postname%/' );
+ wc_setup_loop(
+ array(
+ 'is_shortcode' => false,
+ 'is_paginated' => true,
+ 'total' => 2,
+ 'total_pages' => 2,
+ 'current_page' => 2,
+ )
+ );
+ add_filter( 'get_pagenum_link', $get_pagenum_link_filter, 10, 2 );
+ add_filter( 'woocommerce_pagination_args', $pagination_args_filter );
+
+ ob_start();
+ try {
+ woocommerce_pagination();
+ $markup = (string) ob_get_clean();
+ } finally {
+ while ( ob_get_level() > $buffer_level ) {
+ ob_end_clean();
+ }
+ remove_filter( 'get_pagenum_link', $get_pagenum_link_filter, 10 );
+ remove_filter( 'woocommerce_pagination_args', $pagination_args_filter );
+ $wp_rewrite->set_permalink_structure( $original_permalink_structure );
+ if ( null === $previous_loop ) {
+ wc_reset_loop();
+ } else {
+ $GLOBALS['woocommerce_loop'] = $previous_loop;
+ }
+ }
+
+ $this->assertSame( 'https://example.test/shop/%_%', $pagination_args['base'] );
+ $this->assertSame( 'page/%#%/', $pagination_args['format'] );
+ $this->assertStringContainsString( 'href="https://example.test/shop/"', $markup );
+ }
}