Skip to main content

Overview

The navigation utilities provide a type-safe and convenient way to work with browser navigation, URL construction, search parameters, and history management.

Import

import { 
  createSearchParams,
  formatUrl,
  pushState,
  replaceState,
  hardNavigate
} from "@zayne-labs/toolkit-core";

Functions

createSearchParams

Creates a URLSearchParams object from various input formats.

Signature

function createSearchParams(
  paramsInit?: URLSearchParamsInit
): URLSearchParams

Parameters

paramsInit
URLSearchParamsInit
Search parameters in various formats:
  • string: "key=value&foo=bar"
  • [string, string][]: [["key", "value"], ["foo", "bar"]]
  • Record<string, string | string[]>: { key: "value", tags: ["a", "b"] }
  • URLSearchParams: Existing URLSearchParams instance

Return Value

URLSearchParams
URLSearchParams
A URLSearchParams object.

Example

// From object
const params1 = createSearchParams({ q: "search", page: "1" });

// From string
const params2 = createSearchParams("q=search&page=1");

// From array
const params3 = createSearchParams([["q", "search"], ["page", "1"]]);

// Array values
const params4 = createSearchParams({ 
  tags: ["javascript", "typescript"],
  sort: "date"
});
// Results in: tags=javascript&tags=typescript&sort=date

formatUrl

Formats a URL string or partial URL object into a complete URL with normalized components.

Signature

function formatUrl(
  newURL: string | PartialURLInfo
): FormUrlResult

Parameters

newURL
string | PartialURLInfo
required
URL to format. Can be:
  • A complete URL string
  • A partial URL object with pathname, search, hash, etc.

Return Value

FormUrlResult
object
urlString
string
The complete formatted URL as a string.
urlObject
URLInfoObject
Parsed URL components:
  • pathname: The path portion
  • search: URLSearchParams object
  • searchString: Query string
  • hash: Hash fragment
  • state: Optional state data

Example

// From string
const result1 = formatUrl("/products?category=electronics#reviews");
console.log(result1.urlString); // Full URL
console.log(result1.urlObject.pathname); // "/products"

// From object
const result2 = formatUrl({
  pathname: "/products",
  search: { category: "electronics", sort: "price" },
  hash: "#reviews"
});

pushState

Navigates to a new URL by pushing a new entry to the browser history stack.

Signature

function pushState(
  url: string | PartialURLInfo,
  options?: { state?: unknown }
): void

Parameters

url
string | PartialURLInfo
required
The URL to navigate to.
options
object
options.state
unknown
State data to associate with this history entry.

Example

// Navigate to new page
pushState("/products");

// Navigate with query params
pushState({
  pathname: "/products",
  search: { category: "electronics" }
});

// Navigate with state
pushState("/products", {
  state: { scrollPosition: window.scrollY }
});

replaceState

Replaces the current history entry with a new URL without creating a new history entry.

Signature

function replaceState(
  url: string | PartialURLInfo,
  options?: { state?: unknown }
): void

Parameters

Same as pushState.

Example

// Replace current URL
replaceState("/updated-path");

// Update query params without navigation
replaceState({
  search: { page: "2" }
});

hardNavigate

Performs a full page navigation (browser reload).

Signature

function hardNavigate(
  url: string | Partial<PartialURLInfo> | URL,
  type?: "assign" | "replace"
): void

Parameters

url
string | Partial<PartialURLInfo> | URL
required
The URL to navigate to.
type
'assign' | 'replace'
Navigation type:
  • "assign" (default): Adds to history
  • "replace": Replaces current history entry

Example

// Navigate with page reload
hardNavigate("/login");

// Navigate and replace history
hardNavigate("/home", "replace");

Types

URLSearchParamsInit

type URLSearchParamsInit =
  | string
  | [string, string][]
  | Record<string, string | string[]>
  | URLSearchParams;

PartialURLInfo

type PartialURLInfo = {
  hash?: string;
  pathname?: string;
  search?: URLSearchParamsInit;
  searchString?: string;
  state?: unknown;
};

URLInfoObject

type URLInfoObject = {
  hash: string;
  pathname: string;
  search: URLSearchParams;
  searchString: string;
  state?: unknown;
};

Usage Examples

SPA Navigation

// Navigate between pages in a SPA
function navigateToProduct(productId: string) {
  pushState({
    pathname: `/products/${productId}`,
    state: { from: window.location.pathname }
  });
}

// Listen for navigation
window.addEventListener("popstate", (event) => {
  console.log("Navigated to:", location.pathname);
  console.log("State:", event.state);
});

Search Filters

function updateFilters(filters: Record<string, string>) {
  replaceState({
    search: filters
  });
}

// Update filters without page reload
updateFilters({ 
  category: "electronics", 
  price: "100-500",
  brand: "apple"
});

Pagination

function goToPage(page: number) {
  const { urlObject } = formatUrl(window.location.href);
  
  // Preserve existing params
  urlObject.search.set("page", String(page));
  
  pushState({
    search: urlObject.search
  });
}
// Open modal and update URL
function openModal(modalId: string) {
  pushState(
    { hash: `#modal-${modalId}` },
    { state: { modalOpen: true } }
  );
}

// Close modal
function closeModal() {
  // Remove hash
  replaceState({ hash: "" });
}

Login Redirect

function redirectToLogin() {
  // Save current path for post-login redirect
  const returnUrl = window.location.pathname + window.location.search;
  
  pushState(
    { pathname: "/login", search: { returnUrl } },
    { state: { from: returnUrl } }
  );
}

function handleLoginSuccess() {
  const params = new URLSearchParams(window.location.search);
  const returnUrl = params.get("returnUrl") || "/";
  
  hardNavigate(returnUrl);
}

Building URLs

// Build complex URLs
const { urlString } = formatUrl({
  pathname: "/api/search",
  search: {
    q: "laptop",
    filters: ["brand:dell", "price:500-1000"],
    sort: "price"
  },
  hash: "#results"
});

console.log(urlString);
// https://example.com/api/search?q=laptop&filters=brand:dell&filters=price:500-1000&sort=price#results

Notes

  • All navigation functions work with the current origin by default
  • pushState and replaceState use the History API (no page reload)
  • hardNavigate causes a full page reload
  • Search params with array values are repeated: tags: ["a", "b"] becomes tags=a&tags=b
  • Hash and pathname default to current values if not specified
  • State is preserved in history and accessible via popstate events

Build docs developers (and LLMs) love