I'm trying to add a path alias for a node, /student-&-courses/maths, but in the URL it is displayed as www.testone.com/student-%26-courses/maths.

I unchecked the Generate automatic URL alias option manually set the path alias without adding a pattern. I enabled the Reduce strings to letters and numbers and Transliterate prior to creating alias options in the settings, but it doesn't have any effect: The special characters are not encoded in ASCII format.

How can I fix this so the URL contains special characters?

  • 3
    & is a reserved, not "special", character - you can't create a valid URL without escaping it (see RFC1738). You'll find it hard to get Drupal/pathauto to output an invalid URL, it would be considered a bug, so if you really do need to do something this unusual, you'll probably have to code it yourself
    – Clive
    Feb 12, 2021 at 15:46

2 Answers 2


The ampersand (&) is a reserved character in URLs because it is usually input as part of the query string. Some more info.

Most special characters can be used in URLs with the settings you described in your question, but & is an exception. Either just live with %26 as the encoding or rewrite the title to not use the & symbol, which is reserved.

This is not a Pauthauto problem; it's a URL problem.


As others have said, & is a reserved character with special meaning in urls.

There are a couple options to remove or replace ampersand rather than have it be rewritten to %26 with the pathauto module. Note that these options only apply to aliases that are auto-generated, i.e. when the content has "Generate an automatic URL alias" checked.

The module's settings page (at /admin/config/search/path/settings) has options to remove punctuation or replace punctuation with the default separator. (These options are hidden in the collapsed Punctuation section near the bottom of the form.)

Additionally, pathauto provides an api hook to alter the alias yourself:

 * Alter Pathauto-generated aliases before saving.
 * @param string $alias
 *   The automatic alias after token replacement and strings cleaned.
 * @param array $context
 *   An associative array of additional options, with the following elements:
 *   - 'module': The module or entity type being aliased.
 *   - 'op': A string with the operation being performed on the object being
 *     aliased. Can be either 'insert', 'update', 'return', or 'bulkupdate'.
 *   - 'source': A string of the source path for the alias (e.g. 'node/1').
 *     This can be altered by reference.
 *   - 'data': An array of keyed objects to pass to token_replace().
 *   - 'type': The sub-type or bundle of the object being aliased.
 *   - 'language': A string of the language code for the alias (e.g. 'en').
 *     This can be altered by reference.
 *   - 'pattern': A string of the pattern used for aliasing the object.
function hook_pathauto_alias_alter(&$alias, array &$context) { }

For example, you could use this hook to replace the & with and, but you must first set Ampersand to No action (do not replace) in the pathauto punctuation settings mentioned above.

 * Replace `&` with `and` in generated url paths.
 * Implements hook_pathauto_alias_alter().
function MYMODULE_pathauto_alias_alter(&$alias, array &$context) {
  $alias = str_replace("&", "and", $alias);
  • the path settings do not work even if I select "Reduce strings to letters and numbers" or Punctuation to "No action", I added the above code in my .theme file, still no results
    – Jake13
    Feb 15, 2021 at 20:42
  • I just added some clarifications: 1. These options only apply when the path is being auto-generated (not when you hardcode an alias), 2. You need to set ampersand to be not replaced in the pathauto settings or it will be gone by the time the hook fires, and 3. fixed a typo where the code snippet was missing function in its declaration. I have tested this though and it should work if you implement the hook in a module (I don't think it works in a theme).
    – sonfd
    Feb 15, 2021 at 21:17

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.