Is it possible to spy for the #hash in Next.js 13v apps?
What do I do wrong? Its seems like 'hashchange' event just doesn't work an anaught - only for the first app render.
Now I'm trying to do this, but it's doesn't work:
My layout.tsx:
import './globals.css'
import './page.css'
import type { Metadata } from 'next'
import { TheMenu } from '@/components/TheMenu'
export const metadata: Metadata = {
title: 'Test app',
description: 'Generated by create next app'
}
export default function RootLayout({ children }: { children: React.ReactNode }) {
return (
<html>
<body>
{children}
<TheMenu />
</body>
</html>
)
}
My TheMenu.tsx component - which actually changes the #hash:
'use client'
import './menu.css'
import Link from 'next/link'
import route from '@/config/routing'
import { useState } from 'react'
const TheMenu = () => {
const [open, setOpen] = useState(false)
const toggleMenu = () => {
setOpen(!open)
}
return (
<div className="menu__wrapper">
<button className={`menu__btn`} type="button" onClick={toggleMenu}>
Open/Close
</button>
{open && (
<ul className="menu__list">
{Object.entries(route.modules).map(([key, item]) => (
<li key={key}>
<Link className={`menu__link`} href={item.href} onClick={toggleMenu}>
{item.name}
</Link>
</li>
))}
</ul>
)}
</div>
)
}
export { TheMenu }
And finally page.tsx, where I need to render different components in dependency of current #hash:
'use client'
import route from '@/config/routing'
import { Component1 } from '@/components/other_components/Component1 '
import { Component2 } from '@/components/other_components/Component2 '
import { Barlow } from 'next/font/google'
import { useEffect, useState } from 'react'
const barlow = Barlow({ subsets: ['latin'], weight: '900' })
export default function Home() {
const [component, setComponent] = useState(<Component1 />)
const componentSwitcher = () => {
console.log(window.location.hash)
switch (window.location.hash) {
case '#component1':
setComponent(<Component1 />)
break
case '#component2':
setComponent(<Component2 />)
break
default:
setComponent(<Component1 />)
break
}
}
useEffect(() => {
window.addEventListener('hashchange', componentSwitcher)
componentSwitcher()
return () => {
window.removeEventListener('hashchange', componentSwitcher)
}
}, [])
return (
<>
<div className="container">
<div className="main__wrapper">
<p className={`${barlow.className} welcome__text`}>
Lorem ipsum, dolor sit amet consectetur adipisicing elit. Soluta placeat necessitatibus animi quam, ipsum minima possimus enim cumque nesciunt distinctio.
</p>
</div>
</div>
{component}
</>
)
}