Limit Slug (URL) Length

Limit Slug (URL) Length 1.0.0

No permission to download

mazzly

Well-known member
mazzly submitted a new resource:

Limit Slug (URL) Length - Limit the amount of words in the URL

This add-on creates a new setting under Basic Options called Limit Slug Length:
View attachment 288463

It simply does what it says, shortens the "text"-part (also known as a slug) to be withing the defined number of characters..


Note: It also shortens slugs in the admin, but this will be fine as all things are anyway using the slug.id-format so all pages will work as normal

Read more about this resource...
 
Hello.
What is the prefered number of characters in sense of SEO for Google eg?
I don't know/think there is any benefit for shorter urls.. I would say it's more of a personal preference...

Shorter is ofc easier to type if you would manually ever enter the url... But too short and the context of the title is lost if important words are cut off 😁

A quick Google and it seems the consensus is around 50-75 characters.. If that then also includes the characters of the domain or not, I don't know 😁
 
ooh. nice. would have been even nicer if we could select number of words instead of characters? that would have prevented incomplete words in the title. but still very nice!
 

🧾


Add-on: Limit Slug (URL) Length
Version: 1.0.0
Environment:


  • XenForo: [your XF version, e.g. 2.2.15]
  • Web server: Nginx
  • PHP: 8.x (Debian 12)

Issue Description


When a thread title contains accented characters (like á, é, í, ñ) or special symbols (¿, ¡, emojis, etc.), the generated slug sometimes gets truncated in the middle of a UTF-8 encoded sequence.


For example:
Code:
/threads/les-lleg%C3%B3-esta-falla-alguna-vez-redmi-a1-no-reconoce-su-bater%C3%.92760/

Notice how the sequence %C3% is cut off before completion.
When this happens, Nginx responds with “400 Bad Request”, since the URL is invalid UTF-8.

Cause


In XF/Mvc/Router.php, the code:

Code:
$slug = substr($slug, 0, $limit);

cuts the already URL-encoded string by bytes rather than characters.
This breaks multi-byte sequences (like %C3%B3 for “ó”), producing malformed URLs.


Fix


Replace the unsafe truncation with UTF-8–safe substring logic.
Here’s a fully working fix:

Code:
if ($limit) {
    // Decode before cutting
    $decoded = rawurldecode($slug);

    // Normalize and cut safely by characters (UTF-8 / grapheme)
    if (class_exists('\Normalizer')) {
        $decoded = \Normalizer::normalize($decoded, \Normalizer::FORM_C);
    }

    if (function_exists('grapheme_substr')) {
        $decoded = grapheme_substr($decoded, 0, $limit);
    } else {
        $decoded = mb_substr($decoded, 0, $limit, 'UTF-8');
    }

    // Re-encode and sanitize
    $slug = rawurlencode($decoded);
    $slug = rtrim($slug, '-');
}

This way the slug is cut safely at the character level, not by bytes, and it no longer breaks when thread titles include non-ASCII characters or emojis.


Result


After applying this fix:


  • URLs with accented letters, symbols, or emojis work perfectly.
  • No more “400 Bad Request” errors from Nginx.
  • The add-on continues to enforce the slug length limit properly.
 
Back
Top Bottom