Write a post titled "За нас" on a Bulgarian WordPress site and WordPress gives it the address /за-нас/. It looks fine in the browser's address bar. Copy it into an email, a Viber message or an invoice and it becomes /%D0%B7%D0%B0-%D0%BD%D0%B0%D1%81/. Most Bulgarian sites therefore want Latin addresses, and most get them from a plugin. The trouble is that many of those plugins were written for Russian, so щ turns into shch, ъ disappears and ю becomes ju. This guide explains the official Bulgarian system, the common mistakes, and how to change the addresses of an existing site without losing visitors.
#Are Cyrillic URLs bad for SEO?
Not by themselves. Search engines read Unicode addresses, and a Cyrillic word in the address can even match what people type. The problems are practical:
- Copied links are percent-encoded and three times longer, which looks broken in emails, chats and printed material.
- Some older tools, email clients, ad platforms and server configurations mangle or reject encoded addresses.
- File names of uploads with Cyrillic letters cause trouble on some servers and when files are moved between systems.
- A mixed site, with half the addresses in Cyrillic and half in a home-made Latin, is hard to keep consistent.
If you choose Latin, choose one system and use it everywhere. For Bulgarian there is an obvious candidate.
#What the Transliteration Act says
The Bulgarian Transliteration Act (Закон за транслитерацията, ДВ бр. 19 of 13 March 2009) fixes the so-called Streamlined System. It is the same system you see in passports and on road signs. The letter table is in Article 4:
- а a, б b, в v, г g, д d, е e, ж zh, з z, и i, й y, к k, л l, м m, н n, о o, п p, р r, с s, т t, у u, ф f, х h, ц ts, ч ch, ш sh, щ sht, ъ a, ь y, ю yu, я ya.
Two more rules matter for web addresses. Article 5(2): the letters "ия" at the end of a word are written as "ia", so София is Sofia and Мария is Maria, not Sofiya. Article 6: the name of the state, България, is written Bulgaria, following tradition, while other words follow the table (български is balgarski).
Strictly, Article 2 makes the Act binding on the administration, and for private parties mainly for geographic names and the names of historical figures. Nobody will fine you for the address of a blog post. It is still the best choice for a site, because it is the spelling Bulgarian readers already recognise.
#Typical mistakes of transliteration plugins
Most WordPress transliteration plugins cover many Cyrillic languages with one table, and the table usually comes from Russian. On a Bulgarian site that gives:
- щ as shch: Щастливец becomes shchastlivets instead of shtastlivets.
- ъ dropped or written as y or as an apostrophe: Ябълка becomes yablka instead of yabalka.
- ю and я as ju and ja, х as kh, й as j.
- "ия" as iya at the end of words: istoriya instead of istoria.
- Only post slugs converted, while category and tag slugs and uploaded file names stay in Cyrillic.
Test any tool with a handful of words before you trust it: София, Щастливец, Ябълка, Хасково, Юлиана, България. The right answers are sofia, shtastlivets, yabalka, haskovo, yuliana and bulgaria.
#A minimal do-it-yourself filter
If you only need new slugs, a short filter in a small site plugin or in the theme's functions.php does the job. WordPress runs sanitize_title before it builds a slug; at priority 9 this filter turns Bulgarian letters into Latin first, and WordPress then lowercases the result and adds the dashes:
add_filter('sanitize_title', function ($title, $raw, $context) {
if ($context !== 'save') {
return $title;
}
$map = [
'а' => 'a', 'б' => 'b', 'в' => 'v', 'г' => 'g', 'д' => 'd', 'е' => 'e',
'ж' => 'zh', 'з' => 'z', 'и' => 'i', 'й' => 'y', 'к' => 'k', 'л' => 'l',
'м' => 'm', 'н' => 'n', 'о' => 'o', 'п' => 'p', 'р' => 'r', 'с' => 's',
'т' => 't', 'у' => 'u', 'ф' => 'f', 'х' => 'h', 'ц' => 'ts', 'ч' => 'ch',
'ш' => 'sh', 'щ' => 'sht', 'ъ' => 'a', 'ь' => 'y', 'ю' => 'yu', 'я' => 'ya',
];
$text = mb_strtolower($title, 'UTF-8');
$text = preg_replace('/(?<!\p{L})българия(?!\p{L})/u', 'bulgaria', $text);
$text = preg_replace('/ия(?!\p{L})/u', 'ia', $text);
return strtr($text, $map);
}, 9, 3);
This covers new posts, pages and terms. It does not rename uploaded files, it does not touch addresses that already exist, and it does not redirect anything. For a new site that may be enough. For an existing one, the hard part is the next section.
#Converting the addresses of an existing site
Changing a slug changes a public address. Every link from Google, social networks, newsletters and other sites still points at the old one, so a conversion without redirects turns traffic into 404 pages. Work in this order:
- Back up the database.
- Dry run. List every post, page, attachment, category and tag with its current and new slug, and read the list. Look for collisions, where two old slugs become the same new one.
- Convert in batches, so a large site does not hit the server's time limit, and make the run safe to repeat if it stops halfway.
- Redirect with 301. For posts, WordPress already knows how: when a slug changes it stores the old one in
_wp_old_slugand redirects. Pages, other hierarchical post types and taxonomy terms are not covered by that mechanism and need their own redirects. - Check a sample of old addresses with a browser or
curl -I: each must answer 301 to the new address, and the new address 200. - Let the sitemap regenerate and submit it again in Google Search Console.
Internal links written by hand inside your content keep working through the redirects, but it is cleaner to update them over time.
#How Bukvar does it
We built Bukvar, a WordPress plugin that follows exactly the rules above. It writes new slugs of posts, pages, custom post types and terms, and the names of new uploads, in Latin by the Streamlined System (an uploaded "Снимка на Пловдив.png" is stored as snimka-na-plovdiv.png). Its conversion tool under Settings starts with a dry run that saves nothing, then converts in batches of 50 and can be repeated safely. Converted posts get WordPress's own old-slug record, and Bukvar answers the old addresses of pages and terms with a 301. The same steps run from WP-CLI. Optional Russian and Ukrainian tables handle words in those alphabets, recognised by their own letters.
The transliteration rules are covered by 95 PHPUnit cases, and the plugin by a scripted test on a real WordPress 7.1.3 site that checks the redirects over HTTP. Bukvar is listed as Coming soon; the product page has the details and screenshots.
#Frequently asked questions
Will changing my addresses to Latin hurt my rankings?
A change of address with correct 301 redirects keeps the value of the old links, but search engines need some time to re-crawl. Expect a short period of movement, and do not change addresses twice.
Why is София written Sofia and not Sofiya?
Because Article 5(2) of the Transliteration Act writes the letters "ия" at the end of a word as "ia". Inside a word "я" is still "ya", as in Ябълка, yabalka.
Is ъ really written as a?
Yes. Article 4 of the Act writes ъ as "a", so Търговище is Targovishte. It loses the difference between а and ъ, which is the price of a simple, readable system.
Do I have to follow the Act on my own site?
The Act binds the administration and covers geographic names and names of historical figures in general use. For an ordinary web address it is not mandatory, but it is the spelling your readers already know.
#Sources
- Transliteration Act (Закон за транслитерацията), ДВ бр. 19 of 13 March 2009, Articles 2, 4, 5 and 6
- WordPress developer reference: the sanitize_title filter
Comments
Comments
Be the first to leave a comment.
Leave a comment