Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
Significance: patch
Type: fixed

Fix search blocked by Safari tracking and fingerprint protection
38 changes: 29 additions & 9 deletions projects/packages/search/src/instant-search/lib/query-string.js
Original file line number Diff line number Diff line change
Expand Up @@ -32,12 +32,24 @@ export function setQuery( queryObject ) {
*/
function pushQueryString( queryString ) {
if ( history.pushState ) {
const url = new window.URL( window.location.href );
// Build the target URL directly to avoid Safari tracking protection blocking
// the pattern of creating a URL object and modifying its href property
let baseUrl = window.location.origin + window.location.pathname;

if ( window[ SERVER_OBJECT_NAME ] && 'homeUrl' in window[ SERVER_OBJECT_NAME ] ) {
url.href = window[ SERVER_OBJECT_NAME ].homeUrl;
try {
const homeUrl = window[ SERVER_OBJECT_NAME ].homeUrl;
const parsedHomeUrl = new window.URL( homeUrl, window.location.origin );
baseUrl = parsedHomeUrl.origin + parsedHomeUrl.pathname;
} catch ( error ) {
// Fallback to current location if homeUrl is invalid
// eslint-disable-next-line no-console
console.warn( 'Invalid homeUrl, using current location', error );
}
}
url.search = queryString;
window.history.pushState( null, null, url.toString() );

const finalUrl = baseUrl + ( queryString ? '?' + queryString : '' ) + window.location.hash;
window.history.pushState( null, null, finalUrl );
}
}

Expand Down Expand Up @@ -65,20 +77,28 @@ export function getResultFormatQuery() {
*/
export function restorePreviousHref( initialHref, callback, replaceState = false ) {
if ( history.pushState && history.replaceState ) {
const url = new URL( initialHref );
const queryObject = getQuery( url.search );
// Parse the initial URL to extract components
const parsedUrl = new URL( initialHref );
const queryObject = getQuery( parsedUrl.search );
const keys = [ ...getFilterKeys(), ...getStaticFilterKeys(), 's', 'sort' ];

// If initialHref has search or filter query values, clear them.
const initialHasSearchQueries = Object.keys( queryObject ).some( key => keys.includes( key ) );
if ( initialHasSearchQueries ) {
keys.forEach( key => delete queryObject[ key ] );
}
url.search = encode( queryObject );

// Build the final URL directly to avoid Safari tracking protection issues
const queryString = encode( queryObject );
const finalUrl =
parsedUrl.origin +
parsedUrl.pathname +
( queryString ? '?' + queryString : '' ) +
parsedUrl.hash;

replaceState
? window.history.replaceState( null, null, url.toString() )
: window.history.pushState( null, null, url.toString() );
? window.history.replaceState( null, null, finalUrl )
: window.history.pushState( null, null, finalUrl );

// If initialHref had search queries, then the page rendered beneath the search modal is WordPress's default search page.
// We want to strip these search queries from the URL and direct the user to the root if possible.
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
Significance: patch
Type: bugfix

Fix search blocked by Safari tracking and fingerprint protection
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
Significance: patch
Type: fixed

Fix search blocked by Safari tracking and fingerprint protection
Loading