Next.js页面手动输入URL时丢失查询参数(Query Params)的问题排查与解决请求
Hey there! Let's break down your problem and fix those missing query params once and for all. I see you're coming from mobile development, so I'll keep things clear and avoid overly jargon-heavy explanations where I can.
What's Going On Here?
Your core issues are:
- Manual URL entry loses query params: When you type
https://localhost/explore?name=testedirectly, you get redirected to the non-param version of the page. - Shallow navigation works: Using
route.replacewithshallow: truekeeps the params intact, which makes sense because shallow navigation doesn't reload the entire page component. - Multiple page refreshes lose params: Your page reloads multiple times, and after the first load, the params disappear.
Looking at your code, here are the key culprits:
- SSR vs Client-side hydration mismatch: When you manually enter a URL, Next.js does server-side rendering (SSR) first. Without explicitly passing query params from the server to the client, the client-side hydration can "reset" the params.
- React Strict Mode: Your
next.config.jshasreactStrictMode: true, which in development mode forces components to render twice. This causes the multiple refreshes you're seeing, and can indirectly lead to param loss if your code isn't handling double-renders properly. - Query param formatting in navigation: Your button navigation passes the query as a string (
"name=teste"), which is less reliable than using an object.
Fixes to Try
1. Pass Query Params from Server to Client with getServerSideProps
This is the most reliable way to ensure query params persist across manual URL entries and SSR. Add this to your Explore component:
export default function Explore({ initialQuery }) { const { query } = useRouter() // Use the server-provided params first to avoid hydration gaps const currentQuery = initialQuery || query const router = useRouter() const { data, error } = useSWR(url + "?" + utils.objectToQueryString(currentQuery)) return ( <div className={styles.container}> <main className={styles.main}> <PlacesPanel places={data}/> <div className={styles.rightpanel}> <MapSelector/> </div> </main> </div> ) } // Fetch query params on the server and pass them to the component export async function getServerSideProps(context) { return { props: { initialQuery: context.query // This grabs the URL's query params } } }
Now when you manually enter the URL, the server will capture the params and pass them directly to the component, so they won't get lost during client-side hydration.
2. Fix Your Client-side Navigation Code
Instead of passing the query as a string, use an object format—it's the standard way Next.js expects query params, and avoids parsing issues:
// Replace this: // route.replace({ url: "/explore", query: "name=teste", options: { shallow: true } }) // With this: route.replace({ pathname: "/explore", query: { name: "teste" }, options: { shallow: true } })
3. Check for Hidden Redirects
Double-check your Layout component, _app.js, or any global code for implicit redirects. For example, if there's a router.push("/explore") somewhere that doesn't include the query params, that would wipe them out when the page loads.
4. Disable React Strict Mode Temporarily for Debugging
The multiple refreshes are likely from reactStrictMode: true (it's a development-only feature that double-renders components to catch bugs). If it's making debugging hard, turn it off temporarily in next.config.js:
module.exports = { reactStrictMode: false, // Flip to false for debugging images: { domains: ["i.picsum.photos"], }, }
You can turn it back on for production—this won't affect your live app.
Quick Tips for Mobile Devs Moving to Next.js
- Shallow navigation: Use
shallow: truewhen you don't need to reload the page component (like filtering content without full page refreshes). - Router readiness: Use
router.isReadyto make sure the route is fully loaded before accessingquery—this avoids empty params during hydration:const router = useRouter() useEffect(() => { if (router.isReady) { console.log("Safe to use query params:", router.query) } }, [router.isReady]) - SSR data fetching: Always use
getServerSidePropsorgetStaticProps(depending on your use case) to pass data from server to client—this avoids mismatches between SSR and client-side content.
内容的提问来源于stack exchange,提问作者Matheus Miranda

