Multilanguage in the Ceevee template?


As a first attempt at Grav, I am trying to create a single page using the Ceevee template. However, I need this to be a multilingual page, and am having some troubles…

Multilingual support is enabled, and I can create the modular pages (, etc) and this works fine. However, CeeVee makes use of the onpage_menu, and when I change the title of a page in one of the multilingual modular files, this change not only alters the text visible to the user - it also changes the text used in the link - which then no longer matches the anchor (section id) used by the twig template.

Example: In english, I have a first section called “history”. The onpage menu displays “history” and links to the section called “history”. When I create a german page “” and change the title to “Geschichte”, the text displayed changes to “Geschichte”, but so does the link, while the anchor is still called “history” - so the link does not work.

Second, related problem: The text displayed in the header seems to be single-language. This is the text in site.yaml, for example, the “title” and the “description” in the header. The Ceevee template displays this at the top of the page. How can I make this text multilingual?



Multilingual anchor:
The problem arises because the anchor for each module is hard-coded like ‘<section id=“about”>’. However, the link in the navigation bar is based on the title of the page and converted into an id using the macro ‘pageLinkName(text)’. So, even without using multilingual pages, you would run into problems when you change the title of the page.

Luckily there is an easy way to fix the issue…

Before you make any changes to a theme, you can do yourself a favour by making your own inherited theme. If not, you will loose all changes when the theme gets updated.

Steps to fix the issue:

  • Create inherited theme from ‘ceevee’ if not already.
    Use either of the following two options:
  • Copy file ‘/user/themes/ceevee/templates/modular.html.twig’ into folder ‘/user/themes/mytheme/templates/’
  • In your own copy of ‘modular.html.twig’ modify the for-loop into:
    {% for module in page.collection() %}
       <div id="{{ _self.pageLinkName( }}"></div>
       {{ module.content }}
    {% endfor %}
    Before every module an empty div is created with the proper anchor id.

Multilingual title:

  • Create file ‘/user/themes/mytheme/languages.yaml’
  • Add the following to the file:
          TITLE: I'm Jonathan Doe.
          TITLE: Ich bin der Jonathan Doe.
  • Change <h1> in file ‘templates/partials/header.html.twig’ from…
    <h1 class="responsive-headline">{{ site.header.title }}</h1>
    … into:
    <h1 class="responsive-headline">{{ 'SITE.HEADER.TITLE'|t }}</h1>


Sorry for the delayed response - it’s been kinda crazy… Many thanks for the incredibly detailed and helpful reply. Especially the comment about derived themes, and updates overwriting any changes I would otherwise make. Your answer solved all of my immediate problems - here, mainly because I need multilingual, but picked a template that wasn’t designed with that in mind.

I still have a lot to figure out, but the documentation and forums are a lot of help. Thanks again for your helpful answer!