Jacob Paris
← Back to all content

Submit a form without overwriting existing parameters

This ExistingSearchParams component has been moved to Remix Utils

When you submit a GET form, the form data is serialized to a query string and appended to the URL, where the server will be able to read the data.

If there were any existing parameters in the URL, they will be overwritten. If you have a one form per page system, that makes sense because you'll want to make sure you're always using up-to-date values.

But if you have multiple forms on a page, you'll want to make sure that you're not overwriting the values of other forms.

You can solve this by looping through the existing parameters in the URL and print them out as hidden fields in the form. That way, when the form is submitted, the existing parameters will be preserved.

tsx
const [searchParams] = useSearchParams()
const existingParams = Array.from(searchParams.entries())
return (
<>
{existingParams.map(([key, value]) => {
return (
<input
key={key}
type="hidden"
name={key}
value={value}
/>
)
})}
</>
)

I've added this pattern to Remix Utils as a component called ExistingSearchParams. It takes an optional exclude prop.

Any parameters that should be excluded can be passed in as an array of strings.

  • Most forms will want to exclude their own parameters so there's no duplication
  • You can also use this to clear specific parameters, like resetting the page number when you submit a search form
tsx
import { ExistingSearchParams } from "remix-utils/existing-search-params"
function SearchForm() {
return (
<form method="GET">
<ExistingSearchParams exclude={["q", "page"]} />
<input type="text" name="q" />
<button type="submit">Search</button>
</form>
)
}

Additional props can be passed to the hidden inputs by including them on the ExistingSearchParams component.

For example if you have a pre-existing form component and aren't able to add components inside of it, you can give that form an ID and attach the hidden inputs using the form prop.

tsx
import { ExistingSearchParams } from "remix-utils/existing-search-params"
import { SearchForm } from 'proprietary-search-form-library'
function SearchPage() {
return (
<SearchForm id="search-form" />
<ExistingSearchParams form="search-form" />
)
}
Professional headshot
Moulton
Moulton

Hey there! I'm a developer, designer, and digital nomad building cool things with Remix, and I'm also writing Moulton, the Remix Community Newsletter

About once per month, I send an email with:

  • New guides and tutorials
  • Upcoming talks, meetups, and events
  • Cool new libraries and packages
  • What's new in the latest versions of Remix

Stay up to date with everything in the Remix community by entering your email below.

Unsubscribe at any time.