# Como gerar slug de URL a partir de texto com acentos

> O slug é o trecho legível da URL que vem do título, como acao-e-reacao para "Ação e Reação". Para gerá-lo, é preciso tirar os acentos, passar para minúsculas e trocar o resto por hífens. Este guia mostra como fazer isso em JavaScript, Python e PHP com o mesmo resultado, e os cuidados com slugs repetidos, tamanho e mudanças depois de publicar.

- Endereço oficial: https://pradev.com.br/guias/como-gerar-slug-de-url-com-acentos
- Tipo: Guia
- Publicado em: 2026-10-01
- Atualizado em: 2026-10-01
- Autor: Leonardo Gaertner (https://pradev.com.br/sobre)
- Ferramentas: [Codificar e Decodificar URL](https://pradev.com.br/url-encode-decode), [Remover Acentos do Texto](https://pradev.com.br/remover-acentos-do-texto), [Conversor de Maiúsculas e Minúsculas](https://pradev.com.br/conversor-de-maiusculas-e-minusculas), [Gerador de Slug](https://pradev.com.br/gerador-de-slug)

## Por que não deixar os acentos na URL

Uma URL pode ter acentos, mas eles viajam codificados: `ação` vira `a%C3%A7%C3%A3o`, como mostra o [codificador de URL](https://pradev.com.br/url-encode-decode). Ao copiar e colar o endereço, muita gente vê a forma codificada, que fica ilegível. Um slug só com letras sem acento, números e hífens é curto, legível e funciona igual em qualquer lugar.

## Como tirar os acentos

O truque é a normalização Unicode NFD, que separa cada letra acentuada em duas partes: a letra e o acento. `é` vira `e` seguido do acento agudo, e `ç` vira `c` seguido da cedilha. Depois é só remover os acentos separados, que ficam na faixa `\u0300` a `\u036f`. Para gerar slugs sem programar, use o [gerador de slug](https://pradev.com.br/gerador-de-slug). Para testar com um texto qualquer, use a ferramenta de [remover acentos](https://pradev.com.br/remover-acentos-do-texto), e para converter nomes em `kebab-case` ou `snake_case`, o [conversor de maiúsculas e minúsculas](https://pradev.com.br/conversor-de-maiusculas-e-minusculas).

- Passe para minúsculas.
- Troque tudo que não for letra ou número por hífen, juntando sequências (espaços, pontuação, emojis).
- Tire os hífens das pontas.

```javascript
function gerarSlug(texto) {
  return texto
    .normalize('NFD') // separa a letra do acento: "é" vira "e" + "´"
    .replace(/[̀-ͯ]/g, '') // remove os acentos
    .toLowerCase()
    .replace(/[^a-z0-9]+/g, '-') // o resto (espaços, pontuação) vira hífen
    .replace(/^-+|-+$/g, ''); // sem hífen nas pontas
}

// gerarSlug('Ação & Reação: o básico!') === 'acao-reacao-o-basico'
```

_JavaScript_

## Em Python e PHP

As duas versões fazem a mesma normalização e dão o mesmo resultado do JavaScript. No PHP, a classe `Normalizer` vem da extensão intl. Evite `iconv` com `//TRANSLIT`: o resultado muda conforme o sistema do servidor.

```python
import re
import unicodedata


def gerar_slug(texto: str) -> str:
    # NFD separa a letra do acento; combining() identifica o acento separado
    decomposto = unicodedata.normalize("NFD", texto)
    sem_acento = "".join(c for c in decomposto if not unicodedata.combining(c))
    return re.sub(r"[^a-z0-9]+", "-", sem_acento.lower()).strip("-")
```

_Python_

```php
<?php
// Requer a extensão intl (Normalizer), que vem na maioria das instalações
function gerarSlug(string $texto): string
{
    $decomposto = Normalizer::normalize($texto, Normalizer::FORM_D);
    $semAcento = preg_replace('/\p{Mn}/u', '', $decomposto); // \p{Mn}: os acentos
    return trim(preg_replace('/[^a-z0-9]+/', '-', mb_strtolower($semAcento)), '-');
}
```

_PHP_

## Cuidados

- Slugs repetidos: dois títulos iguais geram o mesmo slug. Antes de salvar, confira no banco e acrescente um número (`-2`, `-3`), ou use um índice único na coluna.
- Tamanho: corte em uns 60 a 80 caracteres, de preferência no último hífen, para não partir uma palavra no meio.
- Não mude o slug depois de publicar. Se precisar mudar, redirecione o endereço antigo para o novo com o código 301, para não perder os links e a posição nas buscas.
- Letras que não são uma letra comum com acento, como `ß` e `ø`, não se decompõem e viram hífen. Para outros idiomas, use uma biblioteca de transliteração.

## Perguntas frequentes

### Como remover acentos de um texto em JavaScript?

Use texto.normalize("NFD").replace(/[\u0300-\u036f]/g, ""). O NFD separa a letra do acento, e o replace remove os acentos, deixando as letras.

### O que é um slug?

É a parte legível da URL que identifica a página, normalmente gerada a partir do título: só letras minúsculas sem acento, números e hífens, como como-gerar-slug.

### Posso usar acentos na URL?

Pode, mas eles são enviados codificados, como %C3%A7 no lugar de ç, e o endereço fica difícil de ler quando copiado. Por isso a maioria dos sites usa slugs sem acento.

### Como evitar slugs repetidos?

Confira se o slug já existe antes de salvar e, se existir, acrescente um número no fim. Uma restrição de valor único no banco garante que dois registros não fiquem com o mesmo slug.

## Fontes

- [MDN: String.prototype.normalize](https://developer.mozilla.org/pt-BR/docs/Web/JavaScript/Reference/Global_Objects/String/normalize)
- [Python: módulo unicodedata](https://docs.python.org/3/library/unicodedata.html)

## Guias relacionados

- [URL encode: como codificar parâmetros de URL sem quebrar nada](https://pradev.com.br/guias/url-encode-como-codificar-parametros): Quando usar encodeURIComponent ou encodeURI, por que o espaço vira + ou %20 e como codificar URL em JavaScript, Python e PHP, com código testado.
- [Regex para CEP, telefone e e-mail no Brasil](https://pradev.com.br/guias/regex-cep-telefone-email): Expressões regulares para validar CEP, telefone com DDD e e-mail, com os erros que deixam passar valores inválidos em JavaScript, Python e PHP.
