Power Pages Error on switching language - incorrectly urlencodes query string

295 views Asked by At

I've set up a blank site in Power Pages with multiple languages (English, French German).

I also have a use case for providing a query string parameter (for example, id).

enter image description here

When using the standard language switcher, the entire query string is url encoded, including the question mark, which results in an ASP.NET error as shown in the image below. I have switched off custom errors in the portal site settings to show the error detail.

enter image description here

Not sure how long this has been happening, but it appears to be a new issue.

2

There are 2 answers

0
Paul Lucas On BEST ANSWER

I raised a ticket with MS and they confirmed a recent change has resulted in this default behavior.

The good news is that it can be switched off with a portal site setting called Site/EnableLanguageDropUrlEncoding.

Set to false to switch off the encoding.

enter image description here

0
fredp613 On

Yes I just ran into this, and (for now) I implemented the following in our header template. It seems like the OOB language.url_substitution liquid object for some reason will encode the URL it accepts and doesnt decode upon return. So adding the script below and adjusting the href to # to pevent default behavior and allow JS to decode is my quick fix since I dont have visibility on the Power Pages server side implementation of url_substitution. I've tested this for performance (1000's of reloads / language picker per few ms) and no failures. Note that I'm still inspecting other PR's from my dev's over the last couple releases to see if this is not a result of another side effect. In any event this works 100% (in my set up).

**OOB language selection template (e.g language dropdown) ** FROM:

<ul class="dropdown-menu" role="menu">
  {% for language in page.languages %}
    <li>
      <a href="{{ language.url_substitution }}" title="{{ language.name }}" data-code="{{ language.code }}">{{ language.name }}</a>
    </li>
    {% endfor %}
</ul>

TO:

<script>
    document.addEventListener('DOMContentLoaded', function() {
      // Select all elements that need URL decoding.
      var links = document.querySelectorAll('a.language-link');
      links.forEach(function(link) {
        // Decode the URL part and set it back on the href attribute.
        link.href = decodeURIComponent(link.getAttribute('data-url'));
      });
    });
  </script>

<ul class="dropdown-menu" role="menu">
  {% for language in page.languages %}
    <li>
      <a href="#" data-url=""/{{ language.url_substitution }}" title="{{ language.name }}" data-code="{{ language.code }}">{{ language.name }}</a>
    </li>
    {% endfor %}
</ul>

My custom template (i only support EN and FR languages so I dont have the drop down rendered, I just have an anchor to click / toggle between langauges

<script>
    document.addEventListener('DOMContentLoaded', function() {
      // Select all elements that need URL decoding.
      var links = document.querySelectorAll('a.language-link');
      links.forEach(function(link) {
        // Decode the URL part and set it back on the href attribute.
        link.href = decodeURIComponent(link.getAttribute('data-url'));
      });
    });
  </script>

<nav class="navbar navbar-dark bg-dark">
    <div id="wb-bnr" class="container">

        <div class="row">
            
            <section id="wb-lng" class="">
                <h2 class="wb-inv">Language selection</h2>

                <ul class="list-inline mrgn-bttm-0 pull-right">
                {% if website.languages.size > 1 %}
                    {% for language in page.languages %}
                        {% if language.name != website.selected_language.name %}
                            <li>
                                <a class="language-link" style="color:white;" data-url="/{{ language.url_substitution }}"  href="#">{{ language.name }}</a>
                            </li>
                        {% endif %}
                    {% endfor %}
                {% endif %}

                </ul>
            </section>
    
        </div>
    </div>
</nav>