swup: Page Class Prefix and nav active classes not updating

Hi there,

Great plugin, the results are excellent. However, I can’t seem to get my header to update nor am I getting the page name added in as a body class at all. The page and the rest of the content load without issue.

Any idea why?

<body>
    <div id="site-container" class="site-container">
        <div class="loading"></div>
        <header class="header" role="banner">
                <div class="header-logo">
                        <a href="/" aria-label="Homepage"></a>
                </div>
                <div class="global-nav-container">
                        <div class="global-nav js-global-nav">
                                <nav class="global-nav-links" data-swup="1">
                                    <a href="/" class="global-nav-link global-nav-link-home ">Home</a>
                                    <a href="/about.html" class="global-nav-link ">About</a>
                                    <a href="/contact.html" class="global-nav-link ">Contact</a>
                                </nav>
                        </div>
                </div>
        </header>
        <main class="main" rel="main">
                <div id="swup" data-swup="0">
                    ...
                </div>
        </main>
    </div>
    <script src="assets/js/swup.min.js"></script>
    <script>
        var swup = new Swup({ pageClassPrefix: 'page-' });
    </script>
</body>

About this issue

  • Original URL
  • State: closed
  • Created 6 years ago
  • Comments: 15 (3 by maintainers)

Most upvoted comments

Just sharing my favorite way to highlight the current page:

function swupActiveLinks(){
    let currentPath = window.location.pathname;
    let links = document.querySelectorAll('nav a'); // <- put your link selector here
    for (const link of links) {
        let linkPath = (new URL( link.href )).pathname;
        link.ariaCurrent = linkPath == currentPath ? 'page' : false;
    }
}
swup.on('contentReplaced', () => {
    swupActiveLinks(); // trigger after swup
});
swupActiveLinks(); // trigger on page load
nav a[aria-current=page]{
  text-decoration: underline;
}

Just a note for anyone using the new Swup 4 that the .on(‘contentReplaced’) hook has changed (https://swup.js.org/getting-started/upgrading/) so it would be the below now:

formerly: swup.on('contentReplaced', () => {}) now: swup.hooks.on('content:replace', () => {})

My solution–

swup.on('contentReplaced', function() {
	var theUrl = stripTrailingSlash(window.location.pathname),
		$theCurrent = document.querySelectorAll('#header .current-menu-item'),
		$newCurrentLink = document.querySelectorAll('.main-menu-link[href*="' + theUrl + '"]');
	
	if($newCurrentLink.length > 0) {
		var $curPar = $newCurrentLink[0].closest('.main-menu-item');
		if($curPar) {
			$curPar.classList.add('current-menu-item');
		}
	}
	
	if($theCurrent.length > 0) {
		$theCurrent[0].classList.remove('current-menu-item');
	}

... ... ... 
function stripTrailingSlash(url)     {     
    return url.replace(/\/$/, "");
} 

First I would make sure to strip the trailing slash off of the url when trying to match it:

var theUrl = window.location.pathname

change to

theUrl = stripTrailingSlash(window.location.pathname)

But your problem sounds like this is not matching an element successfully.

$theCurrent = document.querySelectorAll('#menu-primary-nav .current-menu-item')

which current class does your nav menu actually use??? current_page_item, current-menu-item or both??? Is your menu being generated by wordpress using PHP?