i can't use router.push with shallow
Answered
American black bear posted this in #help-forum
American black bearOP
so i can't use
i need to use
then i can't use
so WTF ?!
import { useRouter } from 'next/router'i need to use
import { useRouter } from 'next/navigation'then i can't use
router.push('/?counter=10', undefined, { shallow: true })so WTF ?!
80 Replies
American black bearOP
this main reason to use shallow is when i'm change a lang from web page
its
refresh
shallow was removed from the app router
you should use useRouter from next/navigation
@American black bear Click to see attachment
American black bearOP
so how i can solve this
even at dashboard page
when its change lang
all data fetched
gone
and need to fetch it again
@American black bear all data fetched
u can use router.replace
@gin u can use router.replace
American black bearOP
wait let me test
@gin u can use router.replace
American black bearOP
same
did u append the currentl url into replace?
can u try this @American black bear
'use client'
import { useSearchParams } from 'next/navigation'
export default function SortProducts() {
const searchParams = useSearchParams()
function updateSorting(sortOrder: string) {
const params = new URLSearchParams(searchParams.toString())
params.set('sort', sortOrder)
window.history.pushState(null, '', `?${params.toString()}`)
}
return (
<>
<button onClick={() => updateSorting('asc')}>Sort Ascending</button>
<button onClick={() => updateSorting('desc')}>Sort Descending</button>
</>
)
}in this case it will be ?sort=asc
American black bearOP
<Dropdown >
<DropdownTrigger>
<Button
variant='light'
className='w-full'
endContent={<Image src={languages.find((code) => code.code === Lang)?.flag} />}
>
</Button>
</DropdownTrigger>
<DropdownMenu aria-label="Example with disabled actions" disabledKeys={["edit", "delete"]}>
{languages.map(({ code, name, flag }) => (
<DropdownItem onPress={() => router.replace(`/${code}/${newPathname}`)} endContent={<Image src={flag} sizes='sm'/>} key={code}>
{name}
</DropdownItem>
))}
</DropdownMenu>
</Dropdown>no see this how i change
lang
yeah remove router.replace
American black bearOP
not parms
ah
'use client'
import { usePathname } from 'next/navigation'
export function LocaleSwitcher() {
const pathname = usePathname()
function switchLocale(locale: string) {
// e.g. '/en/about' or '/fr/contact'
const newPath = `/${locale}${pathname}`
window.history.replaceState(null, '', newPath)
}
return (
<>
<button onClick={() => switchLocale('en')}>English</button>
<button onClick={() => switchLocale('fr')}>French</button>
</>
)
}try this
@gin https://nextjs.org/docs/app/building-your-application/routing/linking-and-navigating#using-the-native-history-api
American black bearOP
now its change a link
amm but
not lang
American black bearOP
@American black bear not lang
is the i18n your own implementation?
@gin is the i18n your own implementation?
American black bearOP
yep
@American black bear yep
show me
American black bearOP
export const fallbackLng = 'en'
export const languages = [fallbackLng, 'de','ar']
export const defaultNS = 'translation'
export const cookieName = 'i18next'
export function getOptions (lng = fallbackLng, ns = defaultNS) {
return {
// debug: true,
supportedLngs: languages,
fallbackLng,
lng,
fallbackNS: defaultNS,
defaultNS,
ns
}
}'use client'
import i18next from 'i18next'
import { useEffect, useState } from 'react'
import { initReactI18next, useTranslation as useTranslationOrg } from 'react-i18next'
import { useCookies } from 'react-cookie'
import resourcesToBackend from 'i18next-resources-to-backend'
import LanguageDetector from 'i18next-browser-languagedetector'
import { getOptions, languages, cookieName } from './settings'
const runsOnServerSide = typeof window === 'undefined'
i18next
.use(initReactI18next)
.use(LanguageDetector)
.use(resourcesToBackend((language, namespace) => import(`./locales/${language}/${namespace}.json`)))
...getOptions(),
lng: undefined,
detection: {
order: ['path', 'htmlTag', 'cookie', 'navigator'],
},
preload: runsOnServerSide ? languages : []
})
export function useTranslation(lng, ns, options) {
const [cookies, setCookie] = useCookies([cookieName])
const ret = useTranslationOrg(ns, options)
const { i18n } = ret
if (runsOnServerSide && lng && i18n.resolvedLanguage !== lng) {
i18n.changeLanguage(lng)
} else {
const [activeLng, setActiveLng] = useState(i18n.resolvedLanguage)
useEffect(() => {
if (activeLng === i18n.resolvedLanguage) return
setActiveLng(i18n.resolvedLanguage)
}, [activeLng, i18n.resolvedLanguage])
useEffect(() => {
if (!lng || i18n.resolvedLanguage === lng) return
i18n.changeLanguage(lng)
}, [lng, i18n])
useEffect(() => {
if (cookies.i18next === lng) return
setCookie(cookieName, lng, { path: '/' })
}, [lng, cookies.i18next])
}
return ret
}// i18n.js
import { createInstance } from 'i18next';
import resourcesToBackend from 'i18next-resources-to-backend';
import { initReactI18next } from 'react-i18next';
import { getOptions } from './settings';
const i18nInstance = createInstance();
// Initialize i18next with default options
i18nInstance
.use(initReactI18next)
.use(
resourcesToBackend((language, namespace) => {
console.log(`Loading resource for language: ${language}, namespace: ${namespace}`);
return import(`./locales/${language}/${namespace}.json`)
.then(module => module.default)
.catch((err) => {
console.error('Error loading resource:', err);
throw err;
});
})
)
.init(getOptions('en', ['main']), (err) => {
if (err) {
console.error('i18n initialization error:', err);
} else {
console.log('i18n initialized successfully');
}
});
export default i18nInstance;import { NextResponse } from 'next/server'
import { NextRequest } from 'next/server'
import acceptLanguage from 'accept-language'
import { fallbackLng, languages, cookieName } from './app/i18n/settings'
acceptLanguage.languages(languages)
export const config = {
// matcher: '/:lng*'
matcher: ['/((?!api|_next/static|_next/image|assets|sound.mp3|public|daily.jpg|downtrend.png|up.png|crown.png|manifest.json|redict|dashboard.svg|gift-svgrepo-com.svg|gift.svg|NuvexLogo.png|NuvexLogo2.png|paper.png|paper.png|placeholder.svg|sparkles-dark.svg|sparkles-dark|favicon.ico|sw.js|site.webmanifest).*)']
}
export function middleware(req: NextRequest) {
console.log(NextRequest)
let lng
if (req.cookies.has(cookieName)) lng = acceptLanguage.get(req.cookies.get(cookieName)?.value)
if (!lng) lng = acceptLanguage.get(req.headers.get('Accept-Language'))
if (!lng) lng = fallbackLng
// Redirect if lng in path is not supported
if (
!languages.some(loc => req.nextUrl.pathname.startsWith(`/${loc}`)) &&
!req.nextUrl.pathname.startsWith('/_next')
) {
return NextResponse.redirect(new URL(`/${lng}${req.nextUrl.pathname}`, req.url))
}
if (req.headers.has('referer')) {
const refererUrl = new URL(req.headers.get('referer') || "")
const lngInReferer = languages.find((l) => refererUrl.pathname.startsWith(`/${l}`))
const response = NextResponse.next()
if (lngInReferer) response.cookies.set(cookieName, lngInReferer)
return response
}
return NextResponse.next()
}done
American black bearOP
i used a youtube vid
u can get the current pathname using usePathname()
and u can listen for that in a useEffect and update your instance
@American black bear Click to see attachment
American black bearOP
you mean
change
this way
to be
useEffect
to
set a lang
from
pathname
in your useStranslation hook
add a new useEffect that depends on pathname
get the language and set with your function
in this case changeLanguage
const pathname = usePathname()
useEffect(() => {
const lng = pathname.split('/')[1]
if (lng !== i18n.resolvedLanguage && languages.includes(lng)) {
i18n.changeLanguage(lng)
}
}, [pathname, i18n])@gin
you the best
its works
now
oh man thanks vvvery much
no problem
glad it works
@gin glad it works
American black bearOP
just one thing
if i goes from main page
to commands
page
its redict
with old
lang
uhm
are u sure the cookie changes
Answer
when u change language
American black bearOP
oh nope wait let me change cookie