Update: it looks like the issue is not related to the custom theme, but rather to a custom authenticator.
When I bind the browser flow to the default browser flow, I can change language without problem.
I don’t understand why it is required to have a response_type in the URL with my custom authenticator set, but with the default UsernamePasswordForm it isn’t. I’d love to hear if someone can explain.
I solved my particular problem in an ugly but effective way: <span class="lang-option"><a href="${l.url}&response_type=code">${l.label}</a></span>
This means that there is no LoginFormsPages defined in FreeMarkerLoginsFormsProvider::createCommonAttributes, resulting in the /protocol/openid-connect path.
I don’t see another solution than this ugly workaround in my custom FTL: