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 );
+	}
 }