1

I am having a bit of an issue: I am trying to setup a rewrite in NextJS that will automatically send on the query string to the destination. However, the only examples I can find are with named params. In this case there could be any number of params, so I need a way of making a wildcard (I assume this will be possible?)

What I am looking to do is the following:

/results?param1=a&param2=b... => https://www.somedomain.com/results?param1=a&param2=b...
or
/results?house=red&car=blue&money=none => https://www.somedomain.com/results??house=red&car=blue&money=none

rewrites() {
    return [ 
      {
        source:'/results?:params*',
        destination:'https://www.somedomain.com/results?:params*'
      },

Of course this doesn't work, so I looked into has but I cannot workout how to make it work without names params

       {
          source: '/some-page',
          destination: '/somewhere-else',
          has: [{ type: 'query', key: 'overrideMe' }],
        },
juliomalves
  • 42,130
  • 20
  • 150
  • 146
Paul A.T. Wilson
  • 854
  • 2
  • 9
  • 18

3 Answers3

0

You can use a standard page like this below. What I did is when the router is initialized in a useEffect hook it gets the query (object) and then use the objectToQueryString function to turn it back into a url encoded string, then used the router to redirect to the other page

// /pages/some-page.jsx
import { useRouter } from 'next/router'
import { useEffect } from 'react'

const objectToQueryString = (initialObj) => {
    const reducer = (obj, parentPrefix = null) => (prev, key) => {
        const val = obj[key];
        key = encodeURIComponent(key);
        const prefix = parentPrefix ? `${parentPrefix}[${key}]` : key;

        if (val == null || typeof val === 'function') {
            prev.push(`${prefix}=`);
            return prev;
        }

        if (['number', 'boolean', 'string'].includes(typeof val)) {
            prev.push(`${prefix}=${encodeURIComponent(val)}`);
            return prev;
        }

        prev.push(Object.keys(val).reduce(reducer(val, prefix), []).join('&'));
        return prev;
    };

    return Object.keys(initialObj).reduce(reducer(initialObj), []).join('&');
};

const Results = () => {
    const router = useRouter()

    useEffect(() => {
        const query = router.query
        router.replace(`https://www.somedomain.com/results?${objectToQueryString(query)}`)
    }, [router])

    return <></>

}
export default Results

I used the objectToQueryString based on Query-string encoding of a Javascript Object

Trevor V
  • 1,958
  • 13
  • 33
  • I have done something similar already, bit I don't really want to redirect, I was the re-write the URL so it all happens within the existing domain. Thanks though. – Paul A.T. Wilson Nov 10 '21 at 16:34
0

To achieve this behavior, you need to capture the value of the query-parameter like this:

rewrites() {
  return [
    {
      source: "/some-page",
      has: [{ type: "query", key: "override_me", value: "(?<override>.*)" }],
      destination: "/somewhere-else?override_me=:override",
    },
  ];
}
Musaddik Rayat
  • 129
  • 1
  • 2
0

By default, a rewrite will pass through any query params that the source URL may have.

In your case, you can simply have the following rewrite rule. All query params will be forwarded through the destination URL.

rewrites() {
  return [ 
    { 
      source: '/results', 
      destination: 'https://www.somedomain.com/results' 
    }
  ]
}
juliomalves
  • 42,130
  • 20
  • 150
  • 146