Files
WooNooW/CANONICAL_REDIRECT_FIX.md
Dwindi Ramadhana f397ef850f feat: Add product images support with WP Media Library integration
- Add WP Media Library integration for product and variation images
- Support images array (URLs) conversion to attachment IDs
- Add images array to API responses (Admin & Customer SPA)
- Implement drag-and-drop sortable images in Admin product form
- Add image gallery thumbnails in Customer SPA product page
- Initialize WooCommerce session for guest cart operations
- Fix product variations and attributes display in Customer SPA
- Add variation image field in Admin SPA

Changes:
- includes/Api/ProductsController.php: Handle images array, add to responses
- includes/Frontend/ShopController.php: Add images array for customer SPA
- includes/Frontend/CartController.php: Initialize WC session for guests
- admin-spa/src/lib/wp-media.ts: Add openWPMediaGallery function
- admin-spa/src/routes/Products/partials/tabs/GeneralTab.tsx: WP Media + sortable images
- admin-spa/src/routes/Products/partials/tabs/VariationsTab.tsx: Add variation image field
- customer-spa/src/pages/Product/index.tsx: Add gallery thumbnails display
2025-11-26 16:18:43 +07:00

5.7 KiB

Fix: Product Page Redirect Issue

Problem

Direct access to product URLs like /product/edukasi-anak redirects to /shop.

Root Cause

WordPress Canonical Redirect

WordPress has a built-in canonical redirect system that redirects "incorrect" URLs to their "canonical" version. When you access /product/edukasi-anak, WordPress doesn't recognize this as a valid WordPress route (because it's a React Router route), so it redirects to the shop page.

How WordPress Canonical Redirect Works

  1. User visits /product/edukasi-anak
  2. WordPress checks if this is a valid WordPress route
  3. WordPress doesn't find a post/page with this URL
  4. WordPress thinks it's a 404 or incorrect URL
  5. WordPress redirects to the nearest valid URL (shop page)

This happens before React Router can handle the URL.


Solution

Disable WordPress canonical redirects for SPA routes.

Implementation

File: includes/Frontend/TemplateOverride.php

1. Hook into Redirect Filter

public static function init() {
    // ... existing code ...
    
    // Disable canonical redirects for SPA routes
    add_filter('redirect_canonical', [__CLASS__, 'disable_canonical_redirect'], 10, 2);
}

2. Add Redirect Handler

/**
 * Disable canonical redirects for SPA routes
 * This prevents WordPress from redirecting /product/slug URLs
 */
public static function disable_canonical_redirect($redirect_url, $requested_url) {
    $settings = get_option('woonoow_customer_spa_settings', []);
    $mode = isset($settings['mode']) ? $settings['mode'] : 'disabled';
    
    // Only disable redirects in full SPA mode
    if ($mode !== 'full') {
        return $redirect_url;
    }
    
    // Check if this is a SPA route
    $spa_routes = ['/product/', '/cart', '/checkout', '/my-account'];
    
    foreach ($spa_routes as $route) {
        if (strpos($requested_url, $route) !== false) {
            // This is a SPA route, disable WordPress redirect
            return false;
        }
    }
    
    return $redirect_url;
}

How It Works

The redirect_canonical Filter

WordPress provides the redirect_canonical filter that allows you to control canonical redirects.

Parameters:

  • $redirect_url - The URL WordPress wants to redirect to
  • $requested_url - The URL the user requested

Return Values:

  • Return $redirect_url - Allow the redirect
  • Return false - Disable the redirect
  • Return different URL - Redirect to that URL instead

Our Logic

  1. Check if SPA mode is enabled
  2. Check if the requested URL contains SPA routes (/product/, /cart, etc.)
  3. If yes, return false to disable redirect
  4. If no, return $redirect_url to allow normal WordPress behavior

Why This Works

Before Fix

User → /product/edukasi-anak
  ↓
WordPress: "This isn't a valid route"
  ↓
WordPress: "Redirect to /shop"
  ↓
React Router never gets a chance to handle the URL

After Fix

User → /product/edukasi-anak
  ↓
WordPress: "Should I redirect?"
  ↓
Our filter: "No, this is a SPA route"
  ↓
WordPress: "OK, loading template"
  ↓
React Router: "I'll handle /product/edukasi-anak"
  ↓
Product page loads correctly

Testing

Test Direct Access

  1. Open new browser tab
  2. Go to: https://woonoow.local/product/edukasi-anak
  3. Should load product page directly
  4. Should NOT redirect to /shop

Test Navigation

  1. Go to /shop
  2. Click a product
  3. Should navigate to /product/slug
  4. Should work correctly

Test Other Routes

  1. /cart - Should work
  2. /checkout - Should work
  3. /my-account - Should work

Check Console

Open browser console and check for logs:

Product Component - Slug: edukasi-anak
Product Component - Current URL: https://woonoow.local/product/edukasi-anak
Product Query - Starting fetch for slug: edukasi-anak
Product API Response: {...}
Product found: {...}

Additional Notes

SPA Routes Protected

The following routes are protected from canonical redirects:

  • /product/ - Product detail pages
  • /cart - Cart page
  • /checkout - Checkout page
  • /my-account - Account pages

Only in Full SPA Mode

This fix only applies when SPA mode is set to full. In other modes, WordPress canonical redirects work normally.

No Impact on SEO

Disabling canonical redirects for SPA routes doesn't affect SEO because:

  1. These are client-side routes handled by React
  2. The actual WordPress product pages still exist
  3. Search engines see the server-rendered content
  4. Canonical URLs are still set in meta tags

Alternative Solutions

Use HashRouter instead of BrowserRouter:

<HashRouter>
  {/* routes */}
</HashRouter>

URLs become: https://woonoow.local/#/product/edukasi-anak

Pros:

  • No server-side configuration needed
  • Works everywhere

Cons:

  • Ugly URLs with #
  • Poor SEO
  • Not modern web standard

Option 2: Custom Rewrite Rules (More Complex)

Add custom WordPress rewrite rules for SPA routes.

Pros:

  • More "proper" WordPress way

Cons:

  • More complex
  • Requires flush_rewrite_rules()
  • Can conflict with other plugins

Option 3: Our Solution (Best)

Disable canonical redirects for SPA routes.

Pros:

  • Clean URLs
  • Simple implementation
  • No conflicts
  • Easy to maintain

Cons:

  • None!

Summary

Problem: WordPress canonical redirect interferes with React Router

Solution: Disable canonical redirects for SPA routes using redirect_canonical filter

Result: Direct product URLs now work correctly!

Files Modified:

  • includes/Frontend/TemplateOverride.php - Added redirect handler

Test: Navigate to /product/edukasi-anak directly - should work!