Skip to content Skip to sidebar

This is the technical support forum for WPML - the multilingual WordPress plugin.

Everyone can read, but only WPML clients can post here. WPML team is replying on the forum 6 days per week, 22 hours per day.

Sun Mon Tue Wed Thu Fri Sat
- 9:00 – 13:00 9:00 – 13:00 9:00 – 13:00 9:00 – 13:00 9:00 – 13:00 -
- 14:00 – 18:00 14:00 – 18:00 14:00 – 18:00 14:00 – 18:00 14:00 – 18:00 -

Supporter timezone: Europe/Kyiv (GMT+03:00)

This topic contains 15 replies, has 0 voices.

Last updated by Andrey 1 week, 4 days ago.

Assisted by: Andrey.

Author Posts
March 31, 2026 at 6:18 pm #17941146

Giulio

Hello,

we are experiencing for a long time an intermittent issue with WooCommerce product URLs when using WPML.

Setup:
- Languages: one default language and one secondary language
- WooCommerce with WPML and WooCommerce Multilingual
- Product permalink structure includes the product category using %product_cat%

The issue: Occasionally, product URLs in the secondary language incorrectly use the category slug from the default language.

This results in mixed-language URLs (secondary language path with default language category slug), which then trigger infinite redirect loops and eventually a “too many redirects” error in the browser.

Important details:
- Category translations are correctly configured and saved in both languages
- Slugs are different and correctly translated
- The issue is intermittent and not consistently reproducible
- It only occurs when %product_cat% is used in the permalink structure
- When the incorrect URL is generated, WPML attempts to redirect to the correct one, but this leads to a redirect loop

What has already been verified:
- Category translations are properly set and not duplicated
- No issues found in WooCommerce Multilingual → Store URLs
- Permalinks have been flushed multiple times
- Caches have been cleared
- No clearly incorrect or duplicate entries found in String Translation

Observations: It appears that, under certain conditions, WPML falls back to the original language category slug instead of using the translated one, even though the translation exists and is correctly configured.

We also found a similar case discussed here: https://wpml.org/forums/topic/product-url-changes-incorrectly-on-secondary-language-too-many-redirects-error/

The behavior described there appears to closely match what we are experiencing.

Questions:

1) Is this a known issue when using %product_cat% in WooCommerce permalinks with WPML?
2) Under what conditions can WPML fallback to the default language slug for taxonomy terms?
3) Are there known issues related to taxonomy synchronization that could cause this behavior intermittently?
4) Would running “Synchronize taxonomies” be recommended in this scenario, or could it introduce side effects?
5) Are there debugging tools or logs available to trace how taxonomy slugs are resolved at runtime?

We are happy to provide further details or debug information if needed.

Thank you.

April 2, 2026 at 3:53 pm #17946641

Andrey
WPML Supporter since 06/2013

Languages: English (English ) Russian (Русский )

Timezone: Europe/Kyiv (GMT+03:00)

Thank you for contacting WPML support.

There are currently no open issues with using %product_cat% in the product permalink structure.

As mentioned regarding the option, I recommend the following:
• Disable the option “WPML fallback to default language” (if enabled), activate "Translatable - only show translated items" in WPML → Settings
• Double-check product categories are properly translated
• Then test the issue again

If the issue still persists, please run an additional test with only the following plugins active:
• WPML
• WooCommerce Multilingual (WCML)
• WooCommerce

April 2, 2026 at 4:12 pm #17946645

Giulio

Thank you for your reply.

I understand the need to isolate the issue by testing with only WPML, WCML and WooCommerce active. However, in this specific case, the issue is intermittent and appears to be related to runtime conditions.

Because of this, replicating the problem in a staging or low-traffic environment would likely not be effective, as the issue does not consistently reproduce and may depend on real traffic, caching layers, or timing.

For this reason, disabling plugins or running tests in an isolated environment would not reliably help us identify the root cause.

I would therefore like to ask if we can approach this differently.

At this point, what we need is to better understand how WPML resolves taxonomy slugs at runtime when using %product_cat%.

Specifically:

1) Under what conditions could WPML fallback to the default language slug even when the translation exists and fallback is disabled?

2) Are there known race conditions or caching interactions affecting taxonomy resolution?

3) Is there a way to log or trace how WPML determines the category slug when generating product URLs?

4) Are there any debug constants, filters, or hooks we can enable to capture this behavior when it occurs?

We are happy to run controlled tests on the live environment (for example, enabling logging or temporarily adjusting settings), but we need guidance on what exactly to monitor.

Given that the issue results in redirect loops, it has a direct impact on usability and SEO, so we would really appreciate a deeper investigation into this behavior.

Thank you.

April 2, 2026 at 4:40 pm #17946679

Andrey
WPML Supporter since 06/2013

Languages: English (English ) Russian (Русский )

Timezone: Europe/Kyiv (GMT+03:00)

Thank you for your feedback.

I understand that the issue appears randomly and, without clear steps to reproduce it, can be difficult to investigate and resolve properly.

Based on what I know so far, here are some clarifications:

1–2) There are currently no known conditions.

3–4) WPML does not provide specific logs, filters, or hooks for tracking this type of behavior.

That said, I recommend enabling WordPress debugging and checking the debug.log file at the moment the issue occurs. This may help capture any underlying errors.

At this stage, the best approach would be to:
• Test with different settings and monitor whether the issue reappears
• Try to identify any pattern or common action that triggers it
• If possible, attempt to reproduce the issue on a staging site, where it can be safely tested

If you’re able to identify reliable steps to reproduce the issue, I’ll be happy to escalate it further to our team for deeper investigation.

April 2, 2026 at 4:47 pm #17946687

Giulio

Thank you for your reply.

We understand the difficulty in investigating an issue that cannot be consistently reproduced. However, since the behavior is intermittent and likely related to runtime conditions, reproducing it on staging is not a reliable approach in this case.

We do have an external developer who can assist us in debugging the issue. However, without any technical direction, it is currently not possible for us to understand where to look or what to monitor.

Given this, it would be very helpful if you could provide guidance on how WPML builds product URLs when using %product_cat%, and where potential failures in taxonomy slug resolution could occur.

At this stage, we kindly ask if this case can be escalated to second-level support, so we can receive more specific technical input and proceed with targeted debugging.

Thank you.

April 2, 2026 at 6:04 pm #17946816

Giulio

Dear Andrey,

thank you for your clarification.

We understand that, without clear steps to reproduce, this can be difficult to investigate.

However, we believe we have already identified some consistent signals that may help narrow down the issue.

In particular:

- The problem affects product URLs in the secondary language when using %product_cat% in the permalink structure

- The category slug occasionally falls back to the default language, resulting in mixed-language URLs

- This triggers redirect loops, as WPML attempts to resolve the correct URL

- Resetting permalinks and purging Litespeed cache immediately resolves the issue, but only temporarily

This behavior suggests that, at certain moments, the permalink may be generated with an incorrect or incomplete taxonomy translation state.

Additionally, while investigating this, we found similar reports online describing very comparable behavior (mixed-language slugs and redirect loops in multilingual setups), which seem consistent with what we are experiencing.

We understand that there are no officially known conditions for this, but based on both our observations and these similar cases, it appears that under certain circumstances the category slug used in the URL may not match the expected language.

In order to proceed with debugging on our side, it would be very helpful to understand where this logic is handled.

Specifically:

1) At which stage WPML resolves the translated product category when building URLs with %product_cat%

2) Which component (WPML core, WCML, or WordPress itself) is responsible for selecting the taxonomy slug in the final URL

3) If there are any hooks, filters, or internal functions involved in this process that we could monitor

We do have a developer available and are fully willing to investigate further, but without insight into how this part of WPML works internally, it is difficult to proceed effectively.

Given that the issue is intermittent and cannot be reliably reproduced, we would appreciate if this could be escalated for a more in-depth technical review.

Thank you again for your support.

April 6, 2026 at 3:15 pm #17951922

Andrey
WPML Supporter since 06/2013

Languages: English (English ) Russian (Русский )

Timezone: Europe/Kyiv (GMT+03:00)

Thank you for your feedback and for taking the time to investigate this further.

Based on the information provided so far, the main challenge is that the issue cannot be reproduced consistently. As you can imagine, this makes it very difficult for us to isolate the root cause or safely escalate the case to our second-tier support team at this stage.

I would also like to mention that similar issues reported recently on the support forum were successfully resolved because they could be reproduced, either consistently or under specific conditions. At the moment, that key element is unfortunately still missing in this case.

Since the behavior appears to be intermittent and environment-specific, the most effective next step would be to continue debugging directly on your installation when the issue occurs. Your developer may find it helpful to:

- Monitor the exact URL and redirect chain when the loop happens
- Check for any filters or custom code affecting permalink generation
- Inspect possible interactions between WPML, WooCommerce, and any SEO or redirect-related plugins
- Enable logging, such as the WordPress debug log or server logs, to capture what happens during the redirect loop

If you can provide more concrete details, such as exact steps to reproduce, relevant logs, or a pattern that consistently triggers the issue, we will be happy to review the case again and reassess whether escalation is warranted.

1) They can review the following file as a possible starting point:
sitepress-multilingual-cms/inc/absolute-links/absolute-links.class.php

However, I cannot guarantee that this is the correct location for your specific case.

2–3) WPML core does include the relevant permalink and language URL handling functionality, but tracing the exact behavior in this situation would require debugging. Your developer should be able to determine which plugin, theme, or WordPress function is involved when the issue occurs.

Our WPML Coding API documentation is available here:
https://wpml.org/documentation/support/wpml-coding-api/

The most effective way to understand what is happening in this case is for your developer to use debugging tools (such as step-by-step debugging with breakpoints) to trace which functions are executed and in what order. This will allow him to identify which plugin, theme, WordPress core function, or custom code is involved, and precisely at what point the redirect behavior is triggered.

I would still strongly recommend focusing first on isolating the issue and finding a reliable way to reproduce it, as I suspect a third-party plugin or theme interaction may be contributing to this behavior.

April 7, 2026 at 12:25 pm #17954193

Giulio

Hello,

our developer has now investigated the issue further and provided additional findings that may help narrow it down.

According to our developer, the class you mentioned seems to be mainly responsible for converting existing links inside saved database content (for example hardcoded links in post_content).

However, our issue appears to happen during dynamic permalink generation, not while processing saved content.

We are seeing it in contexts such as sitemap generation and other runtime permalink generation flows, where product URLs are built dynamically through WordPress/WooCommerce filters.

Because of that, it seems unlikely that absolute-links.class.php is the origin of the issue, although it may still be involved later in the process.

What is your view on this?

To investigate further, we added a debug filter on post_type_link and were able to capture the issue in real time.

Here is an example log entry showing the problem:

```
{
"ts": 1775561645,
"event": "TO BE FIXED",
"post_id": 23689,
"post_slug": "sample-product",
"it_slug": "italian-category-slug",
"en_slug": "english-category-slug",
"wpml_term_id": null,
"original_url": "/en/shop/italian-category-slug/sample-product/",
"fixed_url": "/en/shop/english-category-slug/sample-product/",
"request_uri": "/en/shop/another-category/another-product/?add-to-cart=12345",
"wpml_lang": "en",
"is_admin": false,
"doing_cron": false
}
```

As you can see, the permalink is clearly being generated in an English context (wpml_lang = en, /en/ path), but the category slug inserted into the URL is still the one from the default language.

We are continuing to investigate possible patterns, but this confirms that the glitch is already present at the post_type_link stage.

Do you have any specific technical suggestions based on this log?

We are also attaching the debug code used for this test, in case it helps you understand where the permalink generation flow may be going wrong during initialization.

Any guidance on which WPML/WCML component is responsible for injecting the translated %product_cat% slug at permalink generation time would be very helpful, so we can continue with more targeted tests.

Thank you.

```
<?php

namespace Debug\WPMLSlugIssue;

/**
* Plugin Name: WPML / WCML / WooCommerce - Debug %product_cat%
* Description: Temporary debug helper for multilingual product permalink generation.
*/

define( 'WCML_SLUG_FIX_DEBUG', true );
define( 'WCML_SLUG_FIX_VERBOSE', false );

/**
* Debug Italian category slugs appearing in English product permalinks.
*
* Runs late (priority 99) so it acts as a safety net after WPML/WCML
* have already had their chance to build the URL.
*/
add_filter( 'post_type_link', __NAMESPACE__ . '\debug_wcml_english_category_slug', 99, 4 );
function debug_wcml_english_category_slug(
string $permalink,
\WP_Post $post,
bool $leavename,
bool $sample
): string {

if ( $post->post_type !== 'product' ) {
return $permalink;
}

static $logged_ids = [];
if ( defined( 'WCML_SLUG_FIX_VERBOSE' ) && WCML_SLUG_FIX_VERBOSE ) {
if ( ! isset( $logged_ids[ $post->ID ] ) ) {
$logged_ids[ $post->ID ] = true;
error_log( '[WCML_SLUG_FIX][HEARTBEAT] ' . wp_json_encode( [
'ts' => time(),
'post_id' => $post->ID,
'permalink' => $permalink,
'wpml_lang' => apply_filters( 'wpml_current_language', 'unknown' ),
'is_admin' => is_admin(),
'request_uri' => $_SERVER['REQUEST_URI'] ?? 'CLI/cron',
] ) );
}
}

// Example default-language slugs to watch for.
static $default_language_slugs = [
'default-category-a',
'default-category-b',
'default-category-c',
];

static $slug_cache = [];

$is_english_context = ( strpos( $permalink, '/en/' ) !== false );

if ( ! $is_english_context && function_exists( 'apply_filters' ) ) {
$active_lang = apply_filters( 'wpml_current_language', null );
$is_english_context = ( $active_lang === 'en' );
}

if ( ! $is_english_context ) {
return $permalink;
}

$matched_default_slug = null;

foreach ( $default_language_slugs as $default_slug ) {
if ( strpos( $permalink, '/' . $default_slug . '/' ) !== false ) {
$matched_default_slug = $default_slug;
break;
}
}

if ( $matched_default_slug === null ) {
return $permalink;
}

if ( ! isset( $slug_cache[ $matched_default_slug ] ) ) {
$default_term = get_term_by( 'slug', $matched_default_slug, 'product_cat' );

if ( ! $default_term || is_wp_error( $default_term ) ) {
_wcml_slug_fix_log( 'TERM_NOT_FOUND', $permalink, $post, $matched_default_slug, null );
return $permalink;
}

$translated_term_id = apply_filters(
'wpml_object_id',
$default_term->term_id,
'product_cat',
false,
'en'
);

if ( ! $translated_term_id ) {
_wcml_slug_fix_log( 'EN_TERM_ID_MISSING', $permalink, $post, $matched_default_slug, $default_term->term_id );
return $permalink;
}

$translated_term = get_term( (int) $translated_term_id, 'product_cat' );

if ( ! $translated_term || is_wp_error( $translated_term ) ) {
_wcml_slug_fix_log( 'EN_TERM_INVALID', $permalink, $post, $matched_default_slug, $translated_term_id );
return $permalink;
}

$slug_cache[ $matched_default_slug ] = $translated_term->slug;
}

$en_slug = $slug_cache[ $matched_default_slug ];

if ( $en_slug === $matched_default_slug ) {
_wcml_slug_fix_log( 'SLUGS_IDENTICAL', $permalink, $post, $matched_default_slug, null );
return $permalink;
}

_wcml_slug_fix_log( 'TO BE FIXED', $permalink, $post, $matched_default_slug, null, $en_slug );
return $permalink;
}

function _wcml_slug_fix_log(
string $event,
string $original_url,
\WP_Post $post,
string $default_slug,
?int $wpml_term_id,
?string $en_slug = null,
?string $fixed_url = null
): void {
if ( ! defined( 'WCML_SLUG_FIX_DEBUG' ) || ! WCML_SLUG_FIX_DEBUG ) {
return;
}

$context = [
'ts' => time(),
'event' => $event,
'post_id' => $post->ID,
'post_slug' => $post->post_name,
'it_slug' => $default_slug,
'en_slug' => $en_slug,
'wpml_term_id' => $wpml_term_id,
'original_url' => $original_url,
'fixed_url' => $fixed_url,
'request_uri' => $_SERVER['REQUEST_URI'] ?? 'CLI/cron',
'wpml_lang' => function_exists( 'apply_filters' )
? apply_filters( 'wpml_current_language', 'unknown' )
: 'wpml_unavailable',
'is_admin' => is_admin(),
'doing_cron' => defined( 'DOING_CRON' ) && DOING_CRON,
];

error_log( '[WCML_SLUG_FIX] ' . wp_json_encode( $context ) );
}
```

April 9, 2026 at 6:20 pm #17960390

Andrey
WPML Supporter since 06/2013

Languages: English (English ) Russian (Русский )

Timezone: Europe/Kyiv (GMT+03:00)

Hello,

Thank you for your detailed update and for the additional investigation.

You are making good progress in narrowing down the issue. However, since the problem cannot be reproduced consistently at this stage, we are still unable to determine the exact cause or provide helpful assistance.

The most important next step is to identify a reliable method to replicate the issue. Once you manage to do that, please check whether the problem persists when only WPML, WooCommerce Multilingual (WCML), and WooCommerce are active. If possible, conduct tests using the default theme.

If we can reproduce the issue consistently and it still occurs with only WPML-related components activated, we will be in a much better position to investigate further and escalate it to our second-tier team if necessary.

At this point, without reproducible steps, many factors could influence the issue, making it difficult for us to proceed further.

Please keep us updated on your findings, especially if you can reliably reproduce the issue. We’ll be happy to assist you from there.

April 9, 2026 at 6:32 pm #17960420

Giulio

Hello Andrey,

thank you for your reply.

However, at this stage we need more concrete technical guidance in order to move forward.

In our previous message, our developer raised specific points and questions based on a clear technical analysis. In particular, we explained that the issue occurs during dynamic permalink generation (for example within the post_type_link filter), and not in the processing of saved content.

We also shared a real log example showing the incorrect behavior at that exact stage.

At the moment, we are not receiving any direct feedback on those points, and this makes it difficult for us to continue the investigation.

You mentioned that we are on the right track, but without more specific input we are left without direction.

Could you please review our previous message again and provide a more concrete and responsible answer to the technical questions raised there?

Thank you.

April 10, 2026 at 6:43 pm #17962790

Andrey
WPML Supporter since 06/2013

Languages: English (English ) Russian (Русский )

Timezone: Europe/Kyiv (GMT+03:00)

Thank you for your feedback.

WPML itself does not directly “inject” the %product_cat% slug into the permalink. This is primarily handled by WooCommerce, while WooCommerce Multilingual (WCML) adjusts the values through filters to ensure the correct language is used.

Based on the log you provided, we can see that the incorrect slug is already present at the post_type_link stage, which indicates that the issue occurs earlier in the permalink generation flow. However, without a reliable way to reproduce the issue, it may be influenced by a variety of factors — such as timing, specific types of requests (e.g. AJAX or add-to-cart), or interactions with third-party plugins or custom code.

At this point, we cannot offer more detailed technical advice or conduct a thorough investigation without reproducing the problem, as the underlying cause may differ greatly depending on the circumstances.

We are fully committed to helping you resolve this. To do so effectively, we need a way to observe the issue firsthand. Your developer, already debugging, might be close to spotting a pattern or finding a way to reproduce it, even if it takes multiple attempts.

April 13, 2026 at 9:43 am #17965378

Giulio

We kindly ask you to allow us a bit more time, and therefore to keep this thread open. The analysis and debugging are currently in progress, and we may well need your assistance again.

April 14, 2026 at 11:21 am #17968424

Giulio

We have conducted a deep-dive analysis to identify the exact point where the product permalink is corrupted, specifically why the default-language category slug is being injected into secondary language URLs.

By interleaving trace callbacks between every registered filter in post_type_link, we have captured the following execution flow during a request to the English shop:

Format: [Timestamp][Filter Priority][Callback ID] [Resulting Permalink]

[1776163218][P-1][post_type_link_filter] -> hidden link
[1776163218][P-2][permalink_filter] -> hidden link
[1776163218][P-10][wc_product_post_type_link] -> hidden link <– CORRUPTION POINT
[1776163218][P-10][WC_Post_Data::variation_post_link] -> hidden link
[1776163218][P-10][…translate_product_post_type_link] -> hidden link <– NO FIX APPLIED
[1776163218][P-11][post_type_link] -> hidden link

As you can see, at priority 10, the core WooCommerce function wc_product_post_type_link resolves the placeholder using the default-language slug instead of the translated one, despite the /en/ request context.

Immediately after, the WCML function translate_product_post_type_link (part of sitepress-multilingual-cms) processes the URL but does not detect or correct the slug.

We are currently investigating why wc_product_post_type_link (which relies on get_the_terms) is retrieving terms in the default language instead of the current language context, and why the WCML translation filter does not intercept this specific case to swap the slug.

This issue seems to lie in the interaction between how WooCommerce resolves taxonomy terms and how WPML/WCML filters those terms during this specific hook.

Any insights on why translate_product_post_type_link might skip this correction, or how to ensure that wc_product_post_type_link receives the translated terms, would be greatly appreciated.

April 14, 2026 at 6:32 pm #17969815

Andrey
WPML Supporter since 06/2013

Languages: English (English ) Russian (Русский )

Timezone: Europe/Kyiv (GMT+03:00)

Thank you for providing additional details.

As mentioned earlier, there are no open issues specifically related to the use of %product_cat% in the product permalink structure. However, since the wc_product_post_type_link filter is involved, your case may be similar to a previously known issue.

You can find more details here:
https://wpml.org/errata/woocommerce-multilingual-too-many-redirects-error-when-using-shop-base-with-category-permalinks/

In that case, the issue occurred when:
• Products were set to “Translatable – use translation if available or fallback to default language”
• Product categories were also translatable
• Product permalinks were set to /webshop/%product_cat%/
• Categories were translated, but products were not (fallback mode)

This issue was fixed in WooCommerce Multilingual & Multicurrency 5.5.3.

I recommend the following:
1. Update WCML
From your debug information, I can see you’re using version 5.5.4. If not updated, please update to 5.5.5 to ensure you’re using the latest fixes.

2. Check translation settings
Temporarily disable the option (if you are still using it):
“Translatable – use translation if available or fallback to the default language”
Then run some tests.

3. Apply workaround if needed
If the issue persists, try the code workaround provided in the errata page above.

April 17, 2026 at 8:55 am #17976269

Giulio

We kindly ask you to allow us a bit more time, and therefore to keep this thread open. The analysis and debugging are currently in progress.