This method of developing multilingual functionality for FSE WordPress themes is a good option for small websites and ideal for webmasters who don’t want to use extra plugins and prefer to do everything manually.
The essence of this method is to create a language version for each part of the template, then create page templates for each language version, which will consist of the previously created template parts. We manually insert the language switcher, in the form of a shortcode, into the headers of all language versions. For the slug, we write the code, which I will include below in the article.
Setting up the child theme and creating all the pages
So, let’s start with the assumption that you already have a local server installed on your PC, WordPress installed, and any FSE theme set up.
Next, we create and activate the child theme. You can watch a video on how to do this via the link. For this, I used the Create Block Theme plugin – we use it and then delete it, as it is not needed permanently.
As an example, I am creating a website in two languages – English and French. Given this setup, we create the necessary pages in the admin panel of the site in both language versions that the site needs. For example, in my case, I am creating 6 pages – (Homepage + About Us + Contact) * 2 language versions.
Eng Homepage – Fr Homepage
Eng About Us – Fr About us
Eng Contact- Fr Contact
Creating Template Parts for All Language Versions
In my case, I am only creating the header and footer in two versions. In the English header, we create navigation that leads only to the English versions of the pages, and naturally, all content in it should also be in English. Similarly, for the French version of the template elements.
Creating Page Templates for All Language Versions
Using the previously created template parts, we create page templates according to the following scheme:
French Template:
FR Simple Page = fr header+content+Fr footer
English Template:
EN Simple Page = eng header+content+eng footer
Templates -> add new template -> custom template
In the video, I copied the source code of an existing page template and pasted it into the new one, editing it – we only add those template elements that we created earlier in the language versions (header + footer).
Reading Settings
Now that we have created the main pages, we go to Reading Settings and select our homepage (eng/fr – depending on your choice – my primary language is English) as the main one in the A static page -> homepage field.
Creating Language Switchers
The code below needs to be inserted into the child theme’s functions.php file. These two pieces of code are for creating shortcodes for switching languages, which we will insert on each page of the site.
Language Switcher to French for the English Version of the Page
// Shortcode for English to French switcher
function en_to_fr_switcher($atts) {
$atts = shortcode_atts(
array(
'slug' => '',
'path' => '',
),
$atts
);
// Choose between the slug and path based on which is provided
$url_part = isset($atts['path']) && $atts['path'] ? $atts['path'] : (isset($atts['slug']) ? $atts['slug'] : '');
// Get the URL of the French page
$fr_url = get_home_url(null, 'fr/' . $url_part);
// Return the switcher link
return "<a href='{$fr_url}' class='language-switcher'>Français</a>";
}
add_shortcode('en_to_fr', 'en_to_fr_switcher');
Language Switcher to English for the French Version of the Page
// Shortcode for English to French switcher
function en_to_fr_switcher($atts) {
$atts = shortcode_atts(
array(
'slug' => '',
'path' => '',
),
$atts
);
// Choose between the slug and path based on which is provided
$url_part = (isset($atts['path']) && $atts['path']) ? $atts['path'] : (isset($atts['slug']) ? $atts['slug'] : '');
// Get the URL of the French page
$fr_url = get_home_url(null, 'fr/' . $url_part);
// Return the switcher link
return "<a href='{$fr_url}' class='language-switcher'>Français</a>";
}
add_shortcode('en_to_fr', 'en_to_fr_switcher');
Adding Language Switchers to All Site Pages
We add the shortcode to each page that has a translation, the arguments of the shortcode being the slug or the link to the page without the domain. In the example below, the homepage does not have an argument because it is the main page, but all other pages will have it.
What the shortcode for the About Us page will look like: [fr_to_en slug=”about-us”]
where “about-us” is the page slug, which can be copied from the “slug” field in the Pages section.
In the case where the page has its own child pages, the slugs for their shortcodes will look like in the screenshot below:
Note that for child pages, instead of the slug, we use the path.
Connecting Templates to Pages
In the Pages section -> Page, we select the appropriate templates for each page in the template field.
Generating the lang Tag for Each Language Version of the Page
The code below is for the header.php file. It will dynamically add the language tag of the page, depending on whether the slug /fr/ or /en/ is in its address. Assuming you have French pages with URLs starting with /fr/. The code will look like this:
<!DOCTYPE html>
<html <?php
if (is_page('your-english-page-slug')) {
echo 'lang="en"';
} elseif (is_page('your-french-page-slug')) {
echo 'lang="fr"';
} else {
language_attributes(); // Це встановить мову за замовчуванням
}
?>>
<head>
<meta charset="<?php bloginfo( 'charset' ); ?>">
<?php
if (is_page('your-english-page-slug')) {
echo '<meta http-equiv="Content-Language" content="en">';
} elseif (is_page('your-french-page-slug')) {
echo '<meta http-equiv="Content-Language" content="fr">';
} else {
echo '<meta http-equiv="Content-Language" content="' . get_locale() . '">';
}
?>
<title><?php wp_title(); ?></title>
<?php wp_head(); ?>
</head>
<body <?php body_class(); ?>>
Checking the Language Switcher
The most important thing at the very end is to check each page to ensure:
- the correct template corresponding to its language version is connected;
- the correct shortcode (with slug or path) is inserted on the page;
- all language switchers on each page are clicked and verified to work correctly.
Conclusion
Since this method involves a lot of manual work on each page, I recommend using it for simple sites with a small number of pages and minimal functionality. The big advantage of this method is that it does not require any plugins, so your site will not be slowed down or exposed to vulnerabilities, which is very important for security. A video of how I practiced everything written here: