diff --git a/package.json b/package.json index 6248c0d113c3e7..413adb63274072 100644 --- a/package.json +++ b/package.json @@ -103,6 +103,7 @@ "dragula": "3.7.0", "elasticsearch": "12.0.0-rc5", "elasticsearch-browser": "12.0.0-rc5", + "encode-uri-query": "1.0.0", "even-better": "7.0.2", "expiry-js": "0.1.7", "exports-loader": "0.6.2", diff --git a/src/ui/public/state_management/state_hashing/unhash_url.js b/src/ui/public/state_management/state_hashing/unhash_url.js index 3671b653dee22a..34ad3982a0565c 100644 --- a/src/ui/public/state_management/state_hashing/unhash_url.js +++ b/src/ui/public/state_management/state_hashing/unhash_url.js @@ -3,6 +3,12 @@ import { format as formatUrl, } from 'url'; +import encodeUriQuery from 'encode-uri-query'; + +import { + stringify as stringifyQueryString +} from 'querystring'; + import unhashQueryString from './unhash_query_string'; export default function unhashUrl(urlWithHashes, states) { @@ -26,11 +32,18 @@ export default function unhashUrl(urlWithHashes, states) { if (!appUrlParsed.query) return urlWithHashes; const appQueryWithoutHashes = unhashQueryString(appUrlParsed.query || {}, states); + + // encodeUriQuery implements the less-aggressive encoding done naturally by + // the browser. We use it to generate the same urls the browser would + const appQueryStringWithoutHashes = stringifyQueryString(appQueryWithoutHashes, null, null, { + encodeURIComponent: encodeUriQuery + }); + return formatUrl({ ...urlWithHashesParsed, hash: formatUrl({ pathname: appUrlParsed.pathname, - query: appQueryWithoutHashes, + search: appQueryStringWithoutHashes, }) }); }