diff --git a/src/client/components/ActivityFeed/CollectionList/state.js b/src/client/components/ActivityFeed/CollectionList/state.js
index 9da289bb619..7a85e6d3362 100644
--- a/src/client/components/ActivityFeed/CollectionList/state.js
+++ b/src/client/components/ActivityFeed/CollectionList/state.js
@@ -1,7 +1,7 @@
 import { buildSelectedFilters } from './filters'
 import { SORT_OPTIONS } from './constants'
 import { transformWasPolicyfeedBackProvidedToApi } from './transformers'
-import { parseQueryString } from '../../../utils'
+import { locationToQSParamsWithPage } from '../../../utils/url'
 
 export const TASK_GET_COMPANY_ACTIVITIES_LIST =
   'TASK_GET_COMPANY_ACTIVITIES_LIST'
@@ -26,8 +26,7 @@ export const TASK_GET_INTERACTIONS_COMPANY_NAME =
 export const ID = 'companyActivitiesList'
 
 export const state2props = ({ router, ...state }) => {
-  const queryString = router.location.search.slice(1)
-  const queryParams = parseQueryString(queryString)
+  const queryParams = locationToQSParamsWithPage(router.location)
   const { currentAdviserId } = state
   const { metadata, selectedAdvisers, selectedCompanies, createdByOthers } =
     state[ID]
diff --git a/src/client/components/ActivityFeedFilteredCollectionList/index.jsx b/src/client/components/ActivityFeedFilteredCollectionList/index.jsx
index 697c1509b04..eafddba2bc4 100644
--- a/src/client/components/ActivityFeedFilteredCollectionList/index.jsx
+++ b/src/client/components/ActivityFeedFilteredCollectionList/index.jsx
@@ -8,6 +8,7 @@ import { GridRow, GridCol } from 'govuk-react'
 import { isEmpty } from 'lodash'
 import qs from 'qs'
 
+import { getQueryParamsFromLocation } from '../../utils/url'
 import Task from '../Task'
 import CollectionSort from '../CollectionList/CollectionSort'
 
@@ -34,7 +35,7 @@ const ActivityFeedFilteredCollectionList = ({
   return (
     <Route>
       {({ history, location }) => {
-        const qsParams = qs.parse(location.search.slice(1))
+        const qsParams = getQueryParamsFromLocation(location)
         const initialPage = parseInt(qsParams.page, 10)
         if (defaultQueryParams && isEmpty(qsParams)) {
           history.push({
diff --git a/src/client/components/CollectionList/CollectionSort.jsx b/src/client/components/CollectionList/CollectionSort.jsx
index ff8f894d485..9b70797b0ed 100644
--- a/src/client/components/CollectionList/CollectionSort.jsx
+++ b/src/client/components/CollectionList/CollectionSort.jsx
@@ -1,9 +1,9 @@
 import React from 'react'
 import PropTypes from 'prop-types'
 import { Route } from 'react-router-dom'
-import qs from 'qs'
 import styled from 'styled-components'
 
+import { getQueryParamsFromLocation } from '../../utils/url'
 import { DARK_GREY } from '../../utils/colours'
 import CollectionHeaderRow from './CollectionHeaderRow'
 import RoutedSelect from '../RoutedSelect'
@@ -33,8 +33,8 @@ const CollectionSort = ({ sortOptions, totalPages, ...props }) => {
   return (
     <CollectionHeaderRow {...props} actions={actions}>
       <Route>
-        {({ location: { search } }) => {
-          const searchParams = qs.parse(search.slice(1))
+        {({ location }) => {
+          const searchParams = getQueryParamsFromLocation(location)
           return (
             <StyledSpan data-test="pagination-summary">
               Page {searchParams.page || 1} of {totalPages}
diff --git a/src/client/components/CompanyActivityFeedFilteredCollectionList/index.jsx b/src/client/components/CompanyActivityFeedFilteredCollectionList/index.jsx
index 9706f2e4ba5..98c8cc1730b 100644
--- a/src/client/components/CompanyActivityFeedFilteredCollectionList/index.jsx
+++ b/src/client/components/CompanyActivityFeedFilteredCollectionList/index.jsx
@@ -8,6 +8,7 @@ import { GridRow, GridCol } from 'govuk-react'
 import { isEmpty } from 'lodash'
 import qs from 'qs'
 
+import { getQueryParamsFromLocation } from '../../utils/url'
 import Task from '../Task'
 import CollectionSort from '../CollectionList/CollectionSort'
 
@@ -34,7 +35,7 @@ const CompanyActivityFeedFilteredCollectionList = ({
   return (
     <Route>
       {({ history, location }) => {
-        const qsParams = qs.parse(location.search.slice(1))
+        const qsParams = getQueryParamsFromLocation(location)
         const initialPage = parseInt(qsParams.page, 10)
         if (defaultQueryParams && isEmpty(qsParams)) {
           history.push({
diff --git a/src/client/components/ContactForm/index.jsx b/src/client/components/ContactForm/index.jsx
index 3149a97e34b..383451b4a3d 100644
--- a/src/client/components/ContactForm/index.jsx
+++ b/src/client/components/ContactForm/index.jsx
@@ -1,4 +1,3 @@
-import qs from 'qs'
 import React, { useEffect } from 'react'
 import PropTypes from 'prop-types'
 import _ from 'lodash'
@@ -9,6 +8,7 @@ import Label from '@govuk-react/label'
 
 import multiInstance from '../../utils/multiinstance'
 import { CONTACT_FORM__SUBMIT } from '../../actions'
+import { getQueryParamsFromLocation } from '../../utils/url'
 
 import Form from '../Form'
 import {
@@ -153,9 +153,8 @@ const _ContactForm = ({
           <Main>
             <State>
               {({ referrerUrl, router }) => {
-                const { origin_url, origin_search } = qs.parse(
-                  router.location.search
-                )
+                const { origin_url, origin_search } =
+                  getQueryParamsFromLocation(router.location)
                 const redirectTo = ({ name, id }) => {
                   return origin_url
                     ? appendParamsToUrl(origin_url, origin_search, id, name)
diff --git a/src/client/components/Dashboard/my-tasks/TaskListSelect.jsx b/src/client/components/Dashboard/my-tasks/TaskListSelect.jsx
index b7d5f5ebdd1..927b222174f 100644
--- a/src/client/components/Dashboard/my-tasks/TaskListSelect.jsx
+++ b/src/client/components/Dashboard/my-tasks/TaskListSelect.jsx
@@ -6,6 +6,8 @@ import { get, kebabCase } from 'lodash'
 import qs from 'qs'
 import { FONT_SIZE, FONT_WEIGHTS } from '@govuk-react/constants'
 
+import { getQueryParamsFromLocation } from '../../../utils/url'
+
 const StyledSelect = styled(Select)({
   select: {
     width: '100%',
@@ -21,7 +23,7 @@ const TaskSelect = ({ label, options = [], qsParam }) => {
   const location = useLocation()
   const [value, setValue] = useState()
 
-  const qsParams = qs.parse(location.search.slice(1))
+  const qsParams = getQueryParamsFromLocation(location)
   const initialValue = get(qsParams, qsParam, '')
 
   useEffect(() => setValue(initialValue), [initialValue])
diff --git a/src/client/components/FilterReset/index.jsx b/src/client/components/FilterReset/index.jsx
index f7c45ff2653..cd591ade8ea 100644
--- a/src/client/components/FilterReset/index.jsx
+++ b/src/client/components/FilterReset/index.jsx
@@ -4,7 +4,8 @@ import PropTypes from 'prop-types'
 import styled from 'styled-components'
 import { FONT_SIZE } from '@govuk-react/constants'
 import { isEmpty } from 'lodash'
-import qs from 'qs'
+
+import { parseQueryString } from '../../utils/url'
 
 const StyledButtonLink = styled(ButtonLink)`
   font-size: ${FONT_SIZE.SIZE_16};
@@ -15,7 +16,7 @@ import { ButtonLink } from '../../components'
 const FilterReset = ({ children, ...props }) => (
   <Route>
     {({ history, location: { pathname, search } }) => {
-      const { sortby, page, ...filters } = qs.parse(search.slice(1))
+      const { sortby, page, ...filters } = parseQueryString(search)
       return (
         !isEmpty(filters) && (
           <StyledButtonLink
diff --git a/src/client/components/FilteredCollectionList/index.jsx b/src/client/components/FilteredCollectionList/index.jsx
index 55d0621d509..e35da65eb9a 100644
--- a/src/client/components/FilteredCollectionList/index.jsx
+++ b/src/client/components/FilteredCollectionList/index.jsx
@@ -8,6 +8,7 @@ import { GridRow, GridCol } from 'govuk-react'
 import { isEmpty } from 'lodash'
 import qs from 'qs'
 
+import { getQueryParamsFromLocation } from '../../utils/url'
 import Task from '../Task'
 import Analytics from '../Analytics'
 
@@ -99,7 +100,7 @@ const FilteredCollectionList = ({
   const totalPages = Math.ceil(
     Math.min(count, maxItemsToPaginate) / itemsPerPage
   )
-  const qsParams = qs.parse(location.search.slice(1))
+  const qsParams = getQueryParamsFromLocation(location)
 
   useEffect(() => {
     if (defaultQueryParams && isEmpty(qsParams)) {
diff --git a/src/client/components/Form/index.jsx b/src/client/components/Form/index.jsx
index 69e802d0106..cd6e09ff5e5 100644
--- a/src/client/components/Form/index.jsx
+++ b/src/client/components/Form/index.jsx
@@ -6,6 +6,7 @@ import qs from 'qs'
 import Button from '@govuk-react/button'
 import Link from '@govuk-react/link'
 
+import { getQueryParamsFromLocation } from '../../utils/url'
 import multiInstance from '../../utils/multiinstance'
 import ErrorSummary from '../ErrorSummary'
 import Task from '../Task'
@@ -86,8 +87,7 @@ const _Form = ({
   ...props
 }) => {
   const history = useHistory()
-  const location = useLocation()
-  const qsParams = qs.parse(location.search.slice(1))
+  const qsParams = getQueryParamsFromLocation(useLocation())
 
   useEffect(() => {
     onLoad(initialValues, initialStepIndex)
diff --git a/src/client/components/Pagination/RoutedPagination.jsx b/src/client/components/Pagination/RoutedPagination.jsx
index 44677cd02a3..27c8d7c588f 100644
--- a/src/client/components/Pagination/RoutedPagination.jsx
+++ b/src/client/components/Pagination/RoutedPagination.jsx
@@ -6,6 +6,7 @@ import qs from 'qs'
 import { FONT_SIZE, MEDIA_QUERIES, SPACING } from '@govuk-react/constants'
 import Link from '@govuk-react/link'
 
+import { getQueryParamsFromLocation } from '../../utils/url'
 import { GREY_3, LINK_COLOUR, WHITE } from '../../../client/utils/colours'
 import { PAGINATION_PIECE_PREVIOUS, PAGINATION_PIECE_NEXT } from './constants'
 
@@ -183,13 +184,12 @@ const Pagination = ({
   return (
     <Route>
       {({ history, location }) => {
-        const qsParams = qs.parse(location.search.slice(1))
         const handleOnClick = (pageNumber, e) => {
           e.preventDefault()
           setPage(pageNumber)
           history.push({
             search: qs.stringify({
-              ...qsParams,
+              ...getQueryParamsFromLocation(location),
               page: pageNumber,
             }),
           })
diff --git a/src/client/components/Resource/Paginated.js b/src/client/components/Resource/Paginated.js
index 8d1e548d30b..d2a2e6f0a83 100644
--- a/src/client/components/Resource/Paginated.js
+++ b/src/client/components/Resource/Paginated.js
@@ -5,6 +5,7 @@ import qs from 'qs'
 
 import styled from 'styled-components'
 
+import { getQueryParamsFromLocation } from '../../utils/url'
 import multiInstance from '../../utils/multiinstance'
 import Task from '../Task'
 import LoadingBox from '../Task/LoadingBox'
@@ -94,7 +95,7 @@ const PaginatedResource = multiInstance({
   }) => (
     <Route>
       {({ location }) => {
-        const qsParams = qs.parse(location.search.slice(1))
+        const qsParams = getQueryParamsFromLocation(location)
         const routePage = parseInt(qsParams.page, 10) || 1
         const totalPages = result ? Math.ceil(result.count / pageSize) : 0
         const hasZeroResults = result?.count === 0
diff --git a/src/client/components/RoutedCheckboxGroupField/index.jsx b/src/client/components/RoutedCheckboxGroupField/index.jsx
index 183f79ddd91..647756638be 100644
--- a/src/client/components/RoutedCheckboxGroupField/index.jsx
+++ b/src/client/components/RoutedCheckboxGroupField/index.jsx
@@ -3,6 +3,7 @@ import PropTypes from 'prop-types'
 import { Route } from 'react-router-dom'
 import qs from 'qs'
 
+import { getQueryParamsFromLocation } from '../../utils/url'
 import CheckboxGroupField from '../CheckboxGroupField'
 
 const RoutedCheckboxGroupField = ({ qsParam, ...props }) => {
@@ -14,7 +15,7 @@ const RoutedCheckboxGroupField = ({ qsParam, ...props }) => {
   return (
     <Route>
       {({ history, location }) => {
-        const qsParams = qs.parse(location.search.slice(1))
+        const qsParams = getQueryParamsFromLocation(location)
         return (
           <CheckboxGroupField
             {...props}
diff --git a/src/client/components/RoutedDateField/index.jsx b/src/client/components/RoutedDateField/index.jsx
index 5d84ff8c516..6316ceba0e2 100644
--- a/src/client/components/RoutedDateField/index.jsx
+++ b/src/client/components/RoutedDateField/index.jsx
@@ -3,12 +3,13 @@ import { Route } from 'react-router-dom'
 import qs from 'qs'
 import { get } from 'lodash'
 
+import { getQueryParamsFromLocation } from '../../utils/url'
 import DateField from '../DateField'
 
 const RoutedDateField = ({ qsParamName, ...props }) => (
   <Route>
     {({ location, history }) => {
-      const qsParams = qs.parse(location.search.slice(1))
+      const qsParams = getQueryParamsFromLocation(location)
       return (
         <DateField
           {...props}
diff --git a/src/client/components/RoutedDownloadDataHeader/index.jsx b/src/client/components/RoutedDownloadDataHeader/index.jsx
index bc4a91dcec8..f70525648fb 100644
--- a/src/client/components/RoutedDownloadDataHeader/index.jsx
+++ b/src/client/components/RoutedDownloadDataHeader/index.jsx
@@ -4,6 +4,7 @@ import qs from 'qs'
 import PropTypes from 'prop-types'
 import { isArray } from 'lodash'
 
+import { getQueryParamsFromLocation } from '../../utils/url'
 import DownloadDataHeader from '../DownloadDataHeader'
 
 const isBool = (value) => ['true', 'false'].includes(value)
@@ -30,7 +31,7 @@ const getQueryStringFromQueryParams = (params) => {
 }
 
 const getDownloadLinkFromLocation = (location, baseDownloadLink) => {
-  const { page, ...queryParams } = qs.parse(location.search.slice(1))
+  const { page, ...queryParams } = getQueryParamsFromLocation(location)
   const queryString = getQueryStringFromQueryParams(queryParams)
   return queryString ? `${baseDownloadLink}?${queryString}` : baseDownloadLink
 }
diff --git a/src/client/components/RoutedFilterChips/index.jsx b/src/client/components/RoutedFilterChips/index.jsx
index 2c70f412328..bab89e1c6d2 100644
--- a/src/client/components/RoutedFilterChips/index.jsx
+++ b/src/client/components/RoutedFilterChips/index.jsx
@@ -4,6 +4,7 @@ import qs from 'qs'
 import { Route } from 'react-router-dom'
 import { omit } from 'lodash'
 
+import { getQueryParamsFromLocation } from '../../utils/url'
 import { Chip } from '..'
 
 /**
@@ -33,7 +34,7 @@ const RoutedFilterChips = ({ qsParamName, selectedOptions = [], ...props }) => (
   <Route>
     {({ location, history }) => {
       const clearFilter = (value) => {
-        const qsParams = qs.parse(location.search.slice(1))
+        const qsParams = getQueryParamsFromLocation(location)
         const newQsParams = removeParamFromQs(qsParams, qsParamName, value)
         history.push({ search: qs.stringify(newQsParams) })
       }
diff --git a/src/client/components/RoutedInput/index.jsx b/src/client/components/RoutedInput/index.jsx
index 3b0557b153c..d0b19a2ec9f 100644
--- a/src/client/components/RoutedInput/index.jsx
+++ b/src/client/components/RoutedInput/index.jsx
@@ -4,6 +4,7 @@ import PropTypes from 'prop-types'
 import qs from 'qs'
 import { Route } from 'react-router-dom'
 
+import { getQueryParamsFromLocation } from '../../utils/url'
 import multiInstance from '../../utils/multiinstance'
 import { useTextCaretPosition } from './useTextCaretPosition'
 import {
@@ -40,7 +41,7 @@ const RoutedInput = ({
   return (
     <Route>
       {({ history, location }) => {
-        const qsParams = qs.parse(location.search.slice(1))
+        const qsParams = getQueryParamsFromLocation(location)
         const writeQs = () =>
           history.replace({
             search: qs.stringify({
@@ -99,7 +100,7 @@ export default multiInstance({
       }),
   }),
   componentStateToProps: (cs, { router }, { qsParam }) => {
-    const qsValue = qs.parse(router.location.search.slice(1))[qsParam]
+    const qsValue = getQueryParamsFromLocation(router.location)[qsParam]
     return { ...cs, qsValue }
   },
   reducer: (state, { type, value, selectedValue }) => {
diff --git a/src/client/components/RoutedSelect/index.jsx b/src/client/components/RoutedSelect/index.jsx
index 262f66d786f..1b57624fe88 100644
--- a/src/client/components/RoutedSelect/index.jsx
+++ b/src/client/components/RoutedSelect/index.jsx
@@ -3,12 +3,13 @@ import { Route } from 'react-router-dom'
 import qs from 'qs'
 import { get } from 'lodash'
 
+import { getQueryParamsFromLocation } from '../../utils/url'
 import Select from '../Select'
 
 const RoutedSelect = ({ qsParamName, ...props }) => (
   <Route>
     {({ location, history }) => {
-      const qsParams = qs.parse(location.search.slice(1))
+      const qsParams = getQueryParamsFromLocation(location)
       const initialValue = get(qsParams, qsParamName, '')
       const onChange = (e) => {
         history.push({
diff --git a/src/client/components/RoutedTypeahead/index.jsx b/src/client/components/RoutedTypeahead/index.jsx
index 9321a331cbc..2309621bb9c 100644
--- a/src/client/components/RoutedTypeahead/index.jsx
+++ b/src/client/components/RoutedTypeahead/index.jsx
@@ -6,6 +6,7 @@ import styled from 'styled-components'
 
 import { FONT_WEIGHTS, LINE_HEIGHT } from '@govuk-react/constants'
 
+import { getQueryParamsFromLocation } from '../../utils/url'
 import FieldWrapper from '../Form/elements/FieldWrapper'
 import Typeahead from '../Typeahead'
 
@@ -40,38 +41,35 @@ const RoutedTypeahead = ({
   ...props
 }) => (
   <Route>
-    {({ history, location }) => {
-      const qsParams = qs.parse(location.search.slice(1))
-      return (
-        <StyledFieldWrapper label={label} name={name} hint={hint} {...props}>
-          <Typeahead
-            name={name}
-            aria-label={label ? label : name}
-            placeholder={placeholder}
-            initialOptions={options}
-            closeMenuOnSelect={closeMenuOnSelect}
-            isMulti={isMulti}
-            value={selectedOptions.map(({ value, label }) => ({
-              value,
-              label,
-            }))}
-            loadOptions={loadOptions}
-            noOptionsMessage={noOptionsMessage}
-            onChange={(pickedOptions) => {
-              history.push({
-                search: qs.stringify({
-                  ...qsParams,
-                  ...(!labelAsQueryParam
-                    ? getParamIds(qsParam, pickedOptions)
-                    : getParamLabels(qsParam, pickedOptions)),
-                  page: 1,
-                }),
-              })
-            }}
-          />
-        </StyledFieldWrapper>
-      )
-    }}
+    {({ history, location }) => (
+      <StyledFieldWrapper label={label} name={name} hint={hint} {...props}>
+        <Typeahead
+          name={name}
+          aria-label={label ? label : name}
+          placeholder={placeholder}
+          initialOptions={options}
+          closeMenuOnSelect={closeMenuOnSelect}
+          isMulti={isMulti}
+          value={selectedOptions.map(({ value, label }) => ({
+            value,
+            label,
+          }))}
+          loadOptions={loadOptions}
+          noOptionsMessage={noOptionsMessage}
+          onChange={(pickedOptions) => {
+            history.push({
+              search: qs.stringify({
+                ...getQueryParamsFromLocation(location),
+                ...(!labelAsQueryParam
+                  ? getParamIds(qsParam, pickedOptions)
+                  : getParamLabels(qsParam, pickedOptions)),
+                page: 1,
+              }),
+            })
+          }}
+        />
+      </StyledFieldWrapper>
+    )}
   </Route>
 )
 
diff --git a/src/client/modules/Companies/CollectionList/state.js b/src/client/modules/Companies/CollectionList/state.js
index 01958871bdd..9949239aeba 100644
--- a/src/client/modules/Companies/CollectionList/state.js
+++ b/src/client/modules/Companies/CollectionList/state.js
@@ -1,7 +1,7 @@
 import { buildSelectedFilters } from './filters'
 import { COMPANY_STATUS_OPTIONS, SORT_OPTIONS } from './constants'
 import { transformArchivedToApi, transformPostcodeToApi } from './transformers'
-import { parseQueryString } from '../../../utils'
+import { locationToQSParamsWithPage } from '../../../utils/url'
 
 export const TASK_GET_COMPANIES_LIST = 'TASK_GET_COMPANIES_LIST'
 export const TASK_GET_COMPANIES_METADATA = 'TASK_GET_COMPANIES_METADATA'
@@ -14,8 +14,7 @@ export const ID = 'companiesList'
  * Convert both location and redux state to props
  */
 export const state2props = ({ router, ...state }) => {
-  const queryString = router.location.search.slice(1)
-  const queryParams = parseQueryString(queryString)
+  const queryParams = locationToQSParamsWithPage(router.location)
   const archived = transformArchivedToApi(queryParams.archived)
   const ukPostcode = transformPostcodeToApi(queryParams.uk_postcode)
 
diff --git a/src/client/modules/Companies/CompanyBusinessDetails/LinkGlobalHQ/state.js b/src/client/modules/Companies/CompanyBusinessDetails/LinkGlobalHQ/state.js
index 4440ad77e6f..3194c81892d 100644
--- a/src/client/modules/Companies/CompanyBusinessDetails/LinkGlobalHQ/state.js
+++ b/src/client/modules/Companies/CompanyBusinessDetails/LinkGlobalHQ/state.js
@@ -1,7 +1,7 @@
 import { transformPostcodeToApi } from '../../CollectionList/transformers'
 import { buildSelectedFilters } from './filters'
 import { SORT_OPTIONS } from '../../CollectionList/constants'
-import { parseQueryString } from '../../../../utils'
+import { locationToQSParamsWithPage } from '../../../../utils/url'
 
 export const ID = 'linkGlobalHQ'
 export const SET_GLOBAL_HQ_ID = 'setGlobalHQ'
@@ -12,8 +12,7 @@ export const TASK_SET_GLOBAL_HQ = 'TASK_SET_GLOBAL_HQ'
 export const TASK_REMOVE_GLOBAL_HQ = 'TASK_REMOVE_GLOBAL_HQ'
 
 export const state2props = ({ router, ...state }) => {
-  const queryString = router.location.search.slice(1)
-  const queryParams = parseQueryString(queryString)
+  const queryParams = locationToQSParamsWithPage(router.location)
   const ukPostcode = transformPostcodeToApi(queryParams.uk_postcode)
 
   const { metadata } = state[ID]
diff --git a/src/client/modules/Companies/CompanyBusinessDetails/LinkSubsidiary/state.js b/src/client/modules/Companies/CompanyBusinessDetails/LinkSubsidiary/state.js
index 8070ebca09c..a5011263f1f 100644
--- a/src/client/modules/Companies/CompanyBusinessDetails/LinkSubsidiary/state.js
+++ b/src/client/modules/Companies/CompanyBusinessDetails/LinkSubsidiary/state.js
@@ -1,15 +1,14 @@
 import { transformPostcodeToApi } from '../../CollectionList/transformers'
 import { buildSelectedFilters } from './filters'
 import { SORT_OPTIONS } from '../../CollectionList/constants'
-import { parseQueryString } from '../../../../utils'
+import { locationToQSParamsWithPage } from '../../../../utils/url'
 
 export const ID = 'linkSubsidiary'
 
 export const TASK_GET_SUBSIDIARY_LIST = 'TASK_GET_SUBSIDIARY_LIST'
 
 export const state2props = ({ router, ...state }) => {
-  const queryString = router.location.search.slice(1)
-  const queryParams = parseQueryString(queryString)
+  const queryParams = locationToQSParamsWithPage(router.location)
   const ukPostcode = transformPostcodeToApi(queryParams.uk_postcode)
 
   const { metadata } = state[ID]
diff --git a/src/client/modules/Companies/CompanyOverview/TableCards/state.js b/src/client/modules/Companies/CompanyOverview/TableCards/state.js
index 93fadc211b2..0e78862318d 100644
--- a/src/client/modules/Companies/CompanyOverview/TableCards/state.js
+++ b/src/client/modules/Companies/CompanyOverview/TableCards/state.js
@@ -1,5 +1,5 @@
 import { SORT_OPTIONS } from '../../../Contacts/CollectionList/constants'
-import { parseQueryString } from '../../../../utils'
+import { locationToQSParamsWithPage } from '../../../../utils/url'
 
 export const OVERVIEW_COMPANY_PROJECTS_LIST_ID = 'overviewCompanyProjectsList'
 export const TASK_GET_PROJECT_WON_COUNT = 'TASK_GET_PROJECT_WON_COUNT'
@@ -8,8 +8,7 @@ export const OVERVIEW_COMPANY_EXPORT_WINS_LIST_ID =
 export const TASK_GET_LATEST_EXPORT_WINS = 'TASK_GET_LATEST_EXPORT_WINS'
 
 export const companyProjectsState2props = ({ router, ...state }) => {
-  const queryString = router.location.search.slice(1)
-  const queryParams = parseQueryString(queryString)
+  const queryParams = locationToQSParamsWithPage(router.location)
 
   return {
     ...state[OVERVIEW_COMPANY_PROJECTS_LIST_ID],
@@ -21,8 +20,7 @@ export const companyProjectsState2props = ({ router, ...state }) => {
 }
 
 export const exportWinsState2props = ({ router, ...state }) => {
-  const queryString = router.location.search.slice(1)
-  const queryParams = parseQueryString(queryString)
+  const queryParams = locationToQSParamsWithPage(router.location)
 
   return {
     ...state[OVERVIEW_COMPANY_EXPORT_WINS_LIST_ID],
diff --git a/src/client/modules/Contacts/CollectionList/state.js b/src/client/modules/Contacts/CollectionList/state.js
index 3f8e7c6fc98..02555064d98 100644
--- a/src/client/modules/Contacts/CollectionList/state.js
+++ b/src/client/modules/Contacts/CollectionList/state.js
@@ -1,6 +1,4 @@
-import { omitBy, isEmpty } from 'lodash'
-import qs from 'qs'
-
+import { locationToQSParamsWithPage } from '../../../utils/url'
 import { buildSelectedFilters } from './filters'
 import { transformArchivedToApi } from './transformers'
 import { STATUS_OPTIONS, SORT_OPTIONS } from './constants'
@@ -11,17 +9,8 @@ export const COMPANY_CONTACTS_LIST_ID = 'companyContactsList'
 export const TASK_GET_CONTACTS_LIST = 'TASK_GET_CONTACTS_LIST'
 export const TASK_GET_CONTACTS_METADATA = 'TASK_GET_CONTACTS_METADATA'
 
-const getQueryParams = (router) => {
-  const queryString = router.location.search.slice(1)
-  const queryParams = omitBy({ ...qs.parse(queryString) }, isEmpty)
-  return {
-    ...queryParams,
-    page: parseInt(queryParams.page || 1, 10),
-  }
-}
-
 export const contactsState2props = ({ router, ...state }) => {
-  const queryParams = getQueryParams(router)
+  const queryParams = locationToQSParamsWithPage(router.location)
   const metadata = state[CONTACTS_LIST_ID].metadata
   const selectedFilters = buildSelectedFilters(queryParams, metadata)
   const archived = transformArchivedToApi(queryParams.archived)
@@ -42,7 +31,7 @@ export const contactsState2props = ({ router, ...state }) => {
 }
 
 export const companyContactsState2props = ({ router, ...state }) => {
-  const queryParams = getQueryParams(router)
+  const queryParams = locationToQSParamsWithPage(router.location)
   const archived = transformArchivedToApi(queryParams.archived)
 
   return {
diff --git a/src/client/modules/Contacts/ContactActivity/state.js b/src/client/modules/Contacts/ContactActivity/state.js
index 74f86837d4c..27e65179d74 100644
--- a/src/client/modules/Contacts/ContactActivity/state.js
+++ b/src/client/modules/Contacts/ContactActivity/state.js
@@ -1,12 +1,12 @@
-import qs from 'qs'
+import { getQueryParamsFromLocation } from '../../../utils/url'
 
 export const TASK_GET_CONTACT_ACTIVITIES = 'TASK_GET_CONTACT_ACTIVITIES'
 
 export const ID = 'contactActivity'
 
 export const state2props = ({ ...state }) => {
-  const selectedSortBy = qs.parse(location.search.slice(1)).sortby || 'newest'
-  const page = qs.parse(location.search.slice(1)).page || '1'
+  const selectedSortBy = getQueryParamsFromLocation(location).sortby || 'newest'
+  const page = getQueryParamsFromLocation(location).page || '1'
 
   return {
     ...state[ID],
diff --git a/src/client/modules/Events/AttendeeSearch/state.js b/src/client/modules/Events/AttendeeSearch/state.js
index 48248ea1448..2dc57f55b9b 100644
--- a/src/client/modules/Events/AttendeeSearch/state.js
+++ b/src/client/modules/Events/AttendeeSearch/state.js
@@ -1,6 +1,4 @@
-import { omitBy, isEmpty } from 'lodash'
-import qs from 'qs'
-
+import { locationToQSParamsWithPage } from '../../../utils/url'
 import { SORT_OPTIONS } from '../../Contacts/CollectionList/constants'
 import { buildSelectedFilters } from './filters'
 
@@ -8,17 +6,8 @@ export const TASK_SEARCH_ATTENDEE = 'TASK_SEARCH_ATTENDEE'
 export const TASK_GET_ATTENDEE_METADATA = 'TASK_GET_ATTENDEE_METADATA'
 export const SEARCH_ATTENDEE_ID = 'findAttendees'
 
-const getQueryParams = (router) => {
-  const queryString = router.location.search.slice(1)
-  const queryParams = omitBy({ ...qs.parse(queryString) }, isEmpty)
-  return {
-    ...queryParams,
-    page: parseInt(queryParams.page || 1, 10),
-  }
-}
-
 export const state2props = ({ router, ...state }) => {
-  const queryParams = getQueryParams(router)
+  const queryParams = locationToQSParamsWithPage(router.location)
   const metadata = state[SEARCH_ATTENDEE_ID].metadata
   const selectedFilters = buildSelectedFilters(queryParams, metadata)
 
diff --git a/src/client/modules/Events/CollectionList/state.js b/src/client/modules/Events/CollectionList/state.js
index 501963e066d..03b7a7998fc 100644
--- a/src/client/modules/Events/CollectionList/state.js
+++ b/src/client/modules/Events/CollectionList/state.js
@@ -1,6 +1,6 @@
 import { buildSelectedFilters } from './filters'
 import { SORT_OPTIONS } from './constants'
-import { parseQueryString } from '../../../utils'
+import { locationToQSParamsWithPage } from '../../../utils/url'
 
 export const TASK_GET_EVENTS_LIST = 'TASK_GET_EVENTS_LIST'
 export const TASK_GET_EVENTS_METADATA = 'TASK_GET_EVENTS_METADATA'
@@ -14,8 +14,7 @@ export const ID = 'eventsList'
  * Convert both location and redux state to props
  */
 export const state2props = ({ router, ...state }) => {
-  const queryString = router.location.search.slice(1)
-  const queryParams = parseQueryString(queryString)
+  const queryParams = locationToQSParamsWithPage(router.location)
 
   const { metadata, selectedOrganisers } = state[ID]
 
diff --git a/src/client/modules/Events/EventAventriRegistrationStatus/index.jsx b/src/client/modules/Events/EventAventriRegistrationStatus/index.jsx
index 8fb1c7008f4..cfe7c7a9ee8 100644
--- a/src/client/modules/Events/EventAventriRegistrationStatus/index.jsx
+++ b/src/client/modules/Events/EventAventriRegistrationStatus/index.jsx
@@ -1,7 +1,6 @@
 import React from 'react'
 import { connect } from 'react-redux'
 import { Route } from 'react-router-dom'
-import { isEmpty } from 'lodash'
 import qs from 'qs'
 import { GridCol, GridRow } from 'govuk-react'
 
@@ -65,13 +64,9 @@ const EventAventriRegistrationStatus = ({
   return (
     <Route>
       {({ history, location }) => {
-        const qsParams = qs.parse(location.search.slice(1))
-
-        if (isEmpty(qsParams)) {
+        if (!location.search) {
           history.push({
-            search: qs.stringify({
-              ...defaultQueryParams,
-            }),
+            search: qs.stringify(defaultQueryParams),
           })
         }
 
diff --git a/src/client/modules/Events/EventAventriRegistrationStatus/state.js b/src/client/modules/Events/EventAventriRegistrationStatus/state.js
index f27cdf60924..96d5b5d97f2 100644
--- a/src/client/modules/Events/EventAventriRegistrationStatus/state.js
+++ b/src/client/modules/Events/EventAventriRegistrationStatus/state.js
@@ -1,7 +1,5 @@
-import qs from 'qs'
-
 import { EVENT_ATTENDEES_MAPPING } from '../../../../apps/companies/apps/activity-feed/constants'
-import { parseQueryString } from '../../../utils'
+import { locationToQSParamsWithPage } from '../../../utils/url'
 
 export const TASK_GET_EVENT_AVENTRI_REGISTRATION_STATUS_ATTENDEES =
   'TASK_GET_EVENT_AVENTRI_REGISTRATION_STATUS_ATTENDEES'
@@ -15,12 +13,9 @@ export const mapUrlSlugToRegistrationStatus = (urlSlug) => {
   return Array.isArray(status) ? status[0] : null
 }
 
-export const state2props = (state, router) => {
-  const { match, location } = router
-  const queryString = location.search.slice(1)
-  const queryParams = parseQueryString(queryString)
-  const selectedSortBy =
-    qs.parse(location.search.slice(1)).sortby || 'first_name:asc'
+export const state2props = (state, { match, location }) => {
+  const queryParams = locationToQSParamsWithPage(location)
+  const selectedSortBy = queryParams.sortby || 'first_name:asc'
 
   const registrationStatus = mapUrlSlugToRegistrationStatus(match.params.status)
 
diff --git a/src/client/modules/ExportPipeline/ExportList/ExportSelect.jsx b/src/client/modules/ExportPipeline/ExportList/ExportSelect.jsx
index 97e3d9f7079..656644362dd 100644
--- a/src/client/modules/ExportPipeline/ExportList/ExportSelect.jsx
+++ b/src/client/modules/ExportPipeline/ExportList/ExportSelect.jsx
@@ -5,6 +5,8 @@ import styled from 'styled-components'
 import { get, kebabCase } from 'lodash'
 import qs from 'qs'
 
+import { getQueryParamsFromLocation } from '../../../utils/url'
+
 const StyledSelect = styled(Select)({
   select: {
     width: '100%',
@@ -13,10 +15,8 @@ const StyledSelect = styled(Select)({
 
 const ExportSelect = ({ label, options = [], qsParam }) => {
   const history = useHistory()
-  const location = useLocation()
   const [value, setValue] = useState()
-
-  const qsParams = qs.parse(location.search.slice(1))
+  const qsParams = getQueryParamsFromLocation(useLocation())
   const initialValue = get(qsParams, qsParam, '')
 
   useEffect(() => setValue(initialValue), [initialValue])
diff --git a/src/client/modules/Interactions/CollectionList/state.js b/src/client/modules/Interactions/CollectionList/state.js
index be46495c306..366efc0b5b7 100644
--- a/src/client/modules/Interactions/CollectionList/state.js
+++ b/src/client/modules/Interactions/CollectionList/state.js
@@ -1,7 +1,7 @@
 import { buildSelectedFilters } from './filters'
 import { SORT_OPTIONS } from './constants'
 import { transformWasPolicyfeedBackProvidedToApi } from './transformers'
-import { parseQueryString } from '../../../utils'
+import { locationToQSParamsWithPage } from '../../../utils/url'
 
 export const TASK_GET_INTERACTIONS_LIST = 'TASK_GET_INTERACTIONS_LIST'
 export const TASK_GET_INTERACTIONS_ADVISER_NAME =
@@ -14,8 +14,7 @@ export const TASK_GET_INTERACTIONS_COMPANY_NAME =
 export const ID = 'interactionsList'
 
 export const state2props = ({ router, ...state }) => {
-  const queryString = router.location.search.slice(1)
-  const queryParams = parseQueryString(queryString)
+  const queryParams = locationToQSParamsWithPage(router.location)
   const { currentAdviserId } = state
   const { metadata, selectedAdvisers, selectedTeams, selectedCompanies } =
     state[ID]
diff --git a/src/client/modules/Investments/Opportunities/CollectionList/state.js b/src/client/modules/Investments/Opportunities/CollectionList/state.js
index fd946072398..eb3c96af496 100644
--- a/src/client/modules/Investments/Opportunities/CollectionList/state.js
+++ b/src/client/modules/Investments/Opportunities/CollectionList/state.js
@@ -1,5 +1,4 @@
-import qs from 'qs'
-
+import { getQueryParamsFromLocation } from '../../../../utils/url'
 import { sortOptions } from './metadata'
 
 export const TASK_GET_OPPORTUNITIES_LIST = 'TASK_GET_OPPORTUNITIES_LIST'
@@ -19,7 +18,7 @@ const collectionListPayload = (paramProps) => {
 
 export const state2props = ({ router, ...state }) => {
   const { metadata } = state.opportunitiesList
-  const queryProps = qs.parse(router.location.search.slice(1))
+  const queryProps = getQueryParamsFromLocation(router.location)
   const filteredQueryProps = collectionListPayload(queryProps)
 
   return {
diff --git a/src/client/modules/Investments/Opportunities/OpportunityInteractions.jsx b/src/client/modules/Investments/Opportunities/OpportunityInteractions.jsx
index 3cb9ad05bdf..659c6073330 100644
--- a/src/client/modules/Investments/Opportunities/OpportunityInteractions.jsx
+++ b/src/client/modules/Investments/Opportunities/OpportunityInteractions.jsx
@@ -2,14 +2,14 @@ import React from 'react'
 import { useHistory, useLocation } from 'react-router-dom'
 import qs from 'qs'
 
+import { getQueryParamsFromLocation } from '../../../utils/url'
 import { CollectionList } from '../../../components'
 import { transformInteractionToListItem } from '../../../../apps/interactions/client/transformers'
 import { InteractionCollectionResource } from '../../../components/Resource'
 
 const OpportunityInteractions = ({ opportunityId }) => {
   const history = useHistory()
-  const location = useLocation()
-  const parsedQueryString = qs.parse(location.search.slice(1))
+  const parsedQueryString = getQueryParamsFromLocation(useLocation())
   const activePage = parseInt(parsedQueryString.page, 10) || 1
   return (
     <InteractionCollectionResource
diff --git a/src/client/modules/Investments/Profiles/ProfilesCollection.jsx b/src/client/modules/Investments/Profiles/ProfilesCollection.jsx
index 921c80f3ca8..ae129f93834 100644
--- a/src/client/modules/Investments/Profiles/ProfilesCollection.jsx
+++ b/src/client/modules/Investments/Profiles/ProfilesCollection.jsx
@@ -1,8 +1,8 @@
 import React from 'react'
 import { connect } from 'react-redux'
 import { Route } from 'react-router-dom'
-import qs from 'qs'
 
+import { getQueryParamsFromLocation } from '../../../utils/url'
 import {
   CollectionFilters,
   FilteredCollectionList,
@@ -49,7 +49,7 @@ const LargeCapitalProfileCollection = ({
 }) => (
   <Route>
     {({ location }) => {
-      const qsParams = qs.parse(location.search.slice(1))
+      const qsParams = getQueryParamsFromLocation(location)
       const selectedCountries = resolveSelectedOptions(
         qsParams[QS_PARAMS.countryOfOrigin],
         filterOptions.countries
diff --git a/src/client/modules/Investments/Profiles/state.js b/src/client/modules/Investments/Profiles/state.js
index 1492334aaf1..3adc490124e 100644
--- a/src/client/modules/Investments/Profiles/state.js
+++ b/src/client/modules/Investments/Profiles/state.js
@@ -1,6 +1,7 @@
-import qs from 'qs'
 import { omit } from 'lodash'
 
+import { getQueryParamsFromLocation } from '../../../utils/url'
+
 export const TASK_GET_PROFILES_LIST = 'TASK_GET_PROFILES_LIST'
 
 export const ID = 'profilesList'
@@ -26,5 +27,5 @@ const collectionListPayload = ({
 
 export const state2props = ({ router, ...state }) => ({
   ...state[ID],
-  payload: collectionListPayload(qs.parse(router.location.search.slice(1))),
+  payload: collectionListPayload(getQueryParamsFromLocation(router.location)),
 })
diff --git a/src/client/modules/Investments/Projects/Details/EditAssociatedProject/state.js b/src/client/modules/Investments/Projects/Details/EditAssociatedProject/state.js
index 06d08a64b7b..a165e9f53c5 100644
--- a/src/client/modules/Investments/Projects/Details/EditAssociatedProject/state.js
+++ b/src/client/modules/Investments/Projects/Details/EditAssociatedProject/state.js
@@ -1,4 +1,4 @@
-import { parseQueryString } from '../../../../../utils'
+import { locationToQSParamsWithPage } from '../../../../../utils/url'
 import {
   generateFinancialYearLabel,
   getFinancialYearStart,
@@ -12,9 +12,7 @@ export const TASK_GET_NON_FDI_PROJECTS_LIST = 'TASK_GET_NON_FDI_PROJECTS_LIST'
 export const NON_FDI_LIST_ID = 'nonFdiProjectsList'
 
 export const state2props = ({ router, ...state }) => {
-  const queryString = router.location.search.slice(1)
-
-  const queryParams = parseQueryString(queryString)
+  const queryParams = locationToQSParamsWithPage(router.location)
   const { metadata } = state[NON_FDI_LIST_ID]
   const financialYearStart = getFinancialYearStart(new Date())
   const financialYearOptions = [
diff --git a/src/client/modules/Investments/Projects/Details/EditRecipientCompany/state.js b/src/client/modules/Investments/Projects/Details/EditRecipientCompany/state.js
index 353400d1013..faf4065f717 100644
--- a/src/client/modules/Investments/Projects/Details/EditRecipientCompany/state.js
+++ b/src/client/modules/Investments/Projects/Details/EditRecipientCompany/state.js
@@ -1,4 +1,4 @@
-import { parseQueryString } from '../../../../../utils'
+import { locationToQSParamsWithPage } from '../../../../../utils/url'
 import { transformPostcodeToApi } from '../../../../Companies/CollectionList/transformers'
 import {
   COMPANY_STATUS_OPTIONS,
@@ -12,8 +12,7 @@ export const TASK_UPDATE_RECIPIENT_COMPANY = 'TASK_UPDATE_RECIPIENT_COMPANY'
 export const RECIPIENT_COMPANY_LIST_ID = 'recipientCompanyList'
 
 export const state2props = ({ router, ...state }) => {
-  const queryString = router.location.search.slice(1)
-  const queryParams = parseQueryString(queryString)
+  const queryParams = locationToQSParamsWithPage(router.location)
   const ukPostcode = transformPostcodeToApi(queryParams.uk_postcode)
 
   const { metadata } = state[RECIPIENT_COMPANY_LIST_ID]
diff --git a/src/client/modules/Investments/Projects/ProjectInteractions.jsx b/src/client/modules/Investments/Projects/ProjectInteractions.jsx
index 180b582094a..08c1561848d 100644
--- a/src/client/modules/Investments/Projects/ProjectInteractions.jsx
+++ b/src/client/modules/Investments/Projects/ProjectInteractions.jsx
@@ -4,6 +4,7 @@ import { LEVEL_SIZE } from '@govuk-react/constants'
 import qs from 'qs'
 import { useHistory, useLocation, useParams } from 'react-router-dom'
 
+import { getQueryParamsFromLocation } from '../../../utils/url'
 import { CollectionList } from '../../../components'
 import { transformInteractionToListItem } from '../../../../apps/interactions/client/transformers'
 import { InteractionCollectionResource } from '../../../components/Resource'
@@ -13,8 +14,7 @@ import ProjectLayoutNew from '../../../components/Layout/ProjectLayoutNew'
 
 const ProjectInteractions = () => {
   const history = useHistory()
-  const location = useLocation()
-  const parsedQueryString = qs.parse(location.search.slice(1))
+  const parsedQueryString = getQueryParamsFromLocation(useLocation())
   const activePage = parseInt(parsedQueryString.page, 10) || 1
 
   const { projectId } = useParams()
diff --git a/src/client/modules/Investments/Projects/ProjectPropositions.jsx b/src/client/modules/Investments/Projects/ProjectPropositions.jsx
index 0eecfc76c8a..804e1fb1757 100644
--- a/src/client/modules/Investments/Projects/ProjectPropositions.jsx
+++ b/src/client/modules/Investments/Projects/ProjectPropositions.jsx
@@ -6,6 +6,7 @@ import qs from 'qs'
 import { get } from 'lodash'
 import { useHistory, useLocation, useParams } from 'react-router-dom'
 
+import { getQueryParamsFromLocation } from '../../../utils/url'
 import { CollectionList } from '../../../components'
 import { PropositionCollectionResource } from '../../../components/Resource'
 import urls from '../../../../lib/urls'
@@ -87,8 +88,7 @@ const ProjectPropositions = ({
   completeStatus,
 }) => {
   const history = useHistory()
-  const location = useLocation()
-  const parsedQueryString = qs.parse(location.search.slice(1))
+  const parsedQueryString = getQueryParamsFromLocation(useLocation)
   const activePage = parseInt(parsedQueryString.page, 10) || 1
 
   const { projectId } = useParams()
diff --git a/src/client/modules/Investments/Projects/ProjectTasks.jsx b/src/client/modules/Investments/Projects/ProjectTasks.jsx
index 960b4e036d2..996e2c4cb6f 100644
--- a/src/client/modules/Investments/Projects/ProjectTasks.jsx
+++ b/src/client/modules/Investments/Projects/ProjectTasks.jsx
@@ -1,11 +1,11 @@
 import React from 'react'
 import { H2 } from 'govuk-react'
 import { LEVEL_SIZE } from '@govuk-react/constants'
-import { useParams } from 'react-router-dom'
+import { useParams, useLocation } from 'react-router-dom'
 import { useSearchParam } from 'react-use'
 import { connect } from 'react-redux'
-import qs from 'qs'
 
+import { getQueryParamsFromLocation } from '../../../utils/url'
 import { CollectionList } from '../../../components'
 import { InvestmentProjectTasksResource } from '../../../components/Resource'
 import urls from '../../../../lib/urls'
@@ -19,7 +19,7 @@ import ProjectLayoutNew from '../../../components/Layout/ProjectLayoutNew'
 
 const ProjectTasks = () => {
   const { projectId } = useParams()
-  const parsedQueryString = qs.parse(location.search.slice(1))
+  const parsedQueryString = getQueryParamsFromLocation(useLocation())
   const activePage = parseInt(useSearchParam('page'), 10) || 1
   const getPageUrl = (page) => `${window.location.pathname}?page=${page}`
   const setActivePage = (page) =>
diff --git a/src/client/modules/Investments/Projects/state.js b/src/client/modules/Investments/Projects/state.js
index 6f7feb07c51..b4023a12521 100644
--- a/src/client/modules/Investments/Projects/state.js
+++ b/src/client/modules/Investments/Projects/state.js
@@ -2,7 +2,7 @@ import {
   getFinancialYearStart,
   generateFinancialYearLabel,
 } from '../../../utils/date'
-import { parseQueryString } from '../../../utils'
+import { locationToQSParamsWithPage } from '../../../utils/url'
 import { buildSelectedFilters } from './filters'
 import {
   SORT_OPTIONS,
@@ -31,9 +31,7 @@ export const ID = 'propositionComplete'
 export const TASK_PROPOSITION_COMPLETE = 'TASK_PROPOSITION_COMPLETE'
 
 export const state2props = ({ router, ...state }) => {
-  const queryString = router.location.search.slice(1)
-
-  const queryParams = parseQueryString(queryString)
+  const queryParams = locationToQSParamsWithPage(router.location)
   const { metadata, selectedAdvisers, results } = state[INVESTMENT_PROJECTS_ID]
   const financialYearStart = getFinancialYearStart(new Date())
   const financialYearOptions = [
diff --git a/src/client/modules/Omis/CollectionList/state.js b/src/client/modules/Omis/CollectionList/state.js
index 3068512d346..0785c1a3555 100644
--- a/src/client/modules/Omis/CollectionList/state.js
+++ b/src/client/modules/Omis/CollectionList/state.js
@@ -5,7 +5,7 @@ import {
   STATUSES,
   RECONCILIATION_STATUSES,
 } from './constants'
-import { parseQueryString } from '../../../utils'
+import { locationToQSParamsWithPage } from '../../../utils/url'
 
 export const ORDERS_LIST_ID = 'ordersList'
 export const COMPANY_ORDERS_LIST_ID = 'companyOrdersList'
@@ -18,8 +18,7 @@ export const TASK_GET_ORDERS_RECONCILIATION_METADATA =
   'TASK_GET_ORDERS_RECONCILIATION_METADATA'
 
 export const ordersState2props = ({ router, ...state }) => {
-  const queryString = router.location.search.slice(1)
-  const queryParams = parseQueryString(queryString)
+  const queryParams = locationToQSParamsWithPage(router.location)
   const { metadata } = state[ORDERS_LIST_ID]
   const selectedFilters = buildSelectedFilters(queryParams, metadata)
   return {
@@ -35,8 +34,7 @@ export const ordersState2props = ({ router, ...state }) => {
 }
 
 export const companyOrdersState2props = ({ router, ...state }) => {
-  const queryString = router.location.search.slice(1)
-  const queryParams = parseQueryString(queryString)
+  const queryParams = locationToQSParamsWithPage(router.location)
   return {
     ...state[COMPANY_ORDERS_LIST_ID],
     payload: { ...queryParams },
@@ -49,8 +47,7 @@ export const companyOrdersState2props = ({ router, ...state }) => {
 }
 
 export const reconciliationOrdersState2props = ({ router, ...state }) => {
-  const queryString = router.location.search.slice(1)
-  const queryParams = parseQueryString(queryString)
+  const queryParams = locationToQSParamsWithPage(router.location)
   const { metadata } = state[ORDERS_RECONCILIATION_LIST_ID]
   const selectedFilters = buildSelectedFilters(queryParams, metadata)
   return {
diff --git a/src/client/modules/Omis/CreateOrder/CompanySelect/state.js b/src/client/modules/Omis/CreateOrder/CompanySelect/state.js
index 5b78fd552b3..19061ebf697 100644
--- a/src/client/modules/Omis/CreateOrder/CompanySelect/state.js
+++ b/src/client/modules/Omis/CreateOrder/CompanySelect/state.js
@@ -1,15 +1,14 @@
 import { transformPostcodeToApi } from '../../../Companies/CollectionList/transformers'
 import { buildSelectedFilters } from './filters'
 import { SORT_OPTIONS } from '../../../Companies/CollectionList/constants'
-import { parseQueryString } from '../../../../utils'
+import { locationToQSParamsWithPage } from '../../../../utils/url'
 
 export const ID = 'selectOmisCompany'
 
 export const TASK_GET_COMPANIES = 'TASK_GET_COMPANIES'
 
 export const state2props = ({ router, ...state }) => {
-  const queryString = router.location.search.slice(1)
-  const queryParams = parseQueryString(queryString)
+  const queryParams = locationToQSParamsWithPage(router.location)
   const ukPostcode = transformPostcodeToApi(queryParams.uk_postcode)
 
   const { metadata } = state[ID]
diff --git a/src/client/modules/Reminders/InvestmentsOutstandingPropositionsList.jsx b/src/client/modules/Reminders/InvestmentsOutstandingPropositionsList.jsx
index fa97efb9f74..3422d90a418 100644
--- a/src/client/modules/Reminders/InvestmentsOutstandingPropositionsList.jsx
+++ b/src/client/modules/Reminders/InvestmentsOutstandingPropositionsList.jsx
@@ -3,8 +3,8 @@ import { useLocation } from 'react-router-dom'
 import { connect } from 'react-redux'
 import { SPACING, FONT_SIZE } from '@govuk-react/constants'
 import styled from 'styled-components'
-import qs from 'qs'
 
+import { getQueryParamsFromLocation } from '../../utils/url'
 import { BLACK, GREY_1, GREY_2 } from '../../utils/colours'
 
 import { REMINDERS__OUTSTANDING_PROPOSITIONS_LOADED } from '../../actions'
@@ -32,8 +32,7 @@ const PaginationSummary = styled(Summary)({
 
 const InvestmentsOutstandingPropositionsList = ({ reminders }) => {
   const { results, count } = reminders
-  const location = useLocation()
-  const qsParams = qs.parse(location.search.slice(1))
+  const qsParams = getQueryParamsFromLocation(useLocation())
   const page = parseInt(qsParams.page, 10) || 1
   const totalPages = Math.ceil(
     Math.min(count, maxItemsToPaginate) / itemsPerPage
diff --git a/src/client/modules/Reminders/RemindersLists.jsx b/src/client/modules/Reminders/RemindersLists.jsx
index a0e348e2c8c..bc7e455f926 100644
--- a/src/client/modules/Reminders/RemindersLists.jsx
+++ b/src/client/modules/Reminders/RemindersLists.jsx
@@ -2,8 +2,8 @@ import React from 'react'
 import { useLocation } from 'react-router-dom'
 import { SPACING, FONT_SIZE } from '@govuk-react/constants'
 import styled from 'styled-components'
-import qs from 'qs'
 
+import { getQueryParamsFromLocation } from '../../utils/url'
 import { BLACK } from '../../../client/utils/colours'
 
 import { ID } from './state'
@@ -35,8 +35,7 @@ const RemindersLists = ({
   itemRenderer,
 }) => {
   const { results, count, nextPending } = reminders
-  const location = useLocation()
-  const qsParams = qs.parse(location.search.slice(1))
+  const qsParams = getQueryParamsFromLocation(useLocation())
   const page = parseInt(qsParams.page, 10) || 1
   const totalPages = Math.ceil(
     Math.min(count, maxItemsToPaginate) / itemsPerPage
diff --git a/src/client/modules/Reminders/Settings/RemindersSettings.jsx b/src/client/modules/Reminders/Settings/RemindersSettings.jsx
index c44b63ceb5b..510c3e87217 100644
--- a/src/client/modules/Reminders/Settings/RemindersSettings.jsx
+++ b/src/client/modules/Reminders/Settings/RemindersSettings.jsx
@@ -4,9 +4,9 @@ import styled from 'styled-components'
 import { H2 } from '@govuk-react/heading'
 import { SPACING, LEVEL_SIZE } from '@govuk-react/constants'
 import { first, get } from 'lodash'
-import qs from 'qs'
 import { connect } from 'react-redux'
 
+import { getQueryParamsFromLocation } from '../../../utils/url'
 import { DefaultLayout, RemindersToggleSection } from '../../../components'
 import {
   RemindersSettingsTable,
@@ -270,8 +270,7 @@ export const RemindersSettings = ({
   hasInvestmentFeatureGroup,
   hasExportFeatureGroup,
 }) => {
-  const location = useLocation()
-  const qsParams = qs.parse(location.search.slice(1))
+  const qsParams = getQueryParamsFromLocation(useLocation())
 
   const openSettingsSections = getOpenSettings(qsParams)
   const breadcrumbs = generateBreadcrumbs(openSettingsSections)
diff --git a/src/client/modules/Tasks/TaskDetails/state.js b/src/client/modules/Tasks/TaskDetails/state.js
index 12c4b7c0987..b348f9e8415 100644
--- a/src/client/modules/Tasks/TaskDetails/state.js
+++ b/src/client/modules/Tasks/TaskDetails/state.js
@@ -1,7 +1,6 @@
-import qs from 'qs'
-
 import { transformIdNameToValueLabel } from '../../../transformers'
 import { getTaskBreadcrumbs } from '../TaskForm/state'
+import { getQueryParamsFromLocation } from '../../../utils/url'
 
 export const ID = 'taskDetails'
 
@@ -25,6 +24,6 @@ export const state2props = (state) => {
 
 export const buttonState2props = ({ router }) => {
   const { location } = router
-  const { returnUrl } = qs.parse(location.search.slice(1))
+  const { returnUrl } = getQueryParamsFromLocation(location)
   return { returnUrl: returnUrl }
 }
diff --git a/src/client/modules/Tasks/TaskForm/TaskFormAdd.jsx b/src/client/modules/Tasks/TaskForm/TaskFormAdd.jsx
index 87257fa15d8..594b2004e69 100644
--- a/src/client/modules/Tasks/TaskForm/TaskFormAdd.jsx
+++ b/src/client/modules/Tasks/TaskForm/TaskFormAdd.jsx
@@ -1,8 +1,8 @@
 import React from 'react'
 import { useLocation } from 'react-router-dom'
 import { connect } from 'react-redux'
-import qs from 'qs'
 
+import { getQueryParamsFromLocation } from '../../../utils/url'
 import { DefaultLayout } from '../../../components'
 import Task from '../../../components/Task'
 import {
@@ -120,10 +120,8 @@ const TaskFormAdd = ({
   breadcrumbs,
   companyInvestmentProjects,
 }) => {
-  const { search } = useLocation()
-  const { investmentProjectId, interactionId, copyTaskId } = qs.parse(
-    search.slice(1)
-  )
+  const { investmentProjectId, interactionId, copyTaskId } =
+    getQueryParamsFromLocation(useLocation())
   const taskForm = (
     <TaskForm
       task={task}
diff --git a/src/client/utils/index.js b/src/client/utils/index.js
index 981f2126775..617da464f9e 100644
--- a/src/client/utils/index.js
+++ b/src/client/utils/index.js
@@ -1,5 +1,4 @@
-import { isEmpty, omitBy, isPlainObject, camelCase } from 'lodash'
-import qs from 'qs'
+import { isPlainObject, camelCase } from 'lodash'
 
 export const idNameToValueLabel = ({ id, name }) => ({
   value: id,
@@ -8,14 +7,6 @@ export const idNameToValueLabel = ({ id, name }) => ({
 
 export const idNamesToValueLabels = (idNames) => idNames.map(idNameToValueLabel)
 
-export const parseQueryString = (queryString) => {
-  const queryParams = omitBy({ ...qs.parse(queryString) }, isEmpty)
-  return {
-    ...queryParams,
-    page: parseInt(queryParams.page || 1, 10),
-  }
-}
-
 export const deepKeysToCamelCase = (x) =>
   Array.isArray(x)
     ? x.map(deepKeysToCamelCase)
diff --git a/src/client/utils/url.js b/src/client/utils/url.js
index da95d8b56f6..6a3015cf20e 100644
--- a/src/client/utils/url.js
+++ b/src/client/utils/url.js
@@ -1,7 +1,15 @@
-import { omitBy, isEmpty } from 'lodash'
-import qs from 'qs'
+export const parseQueryString = (queryString) =>
+  Object.fromEntries(new URLSearchParams(queryString).entries())
 
-export const getQueryParamsFromLocation = (location) => {
-  const queryString = location.search.slice(1)
-  return omitBy({ ...qs.parse(queryString) }, isEmpty)
+// TODO: Rename to locationToQSParams
+export const getQueryParamsFromLocation = (location) =>
+  parseQueryString(location.search)
+
+export const locationToQSParamsWithPage = (location) => {
+  const queryParams = parseQueryString(location.search)
+
+  return {
+    ...queryParams,
+    page: parseInt(queryParams.page || 1, 10),
+  }
 }