navigate()

Environment: client.

The navigate('/some/url') function enables you to programmatically switch pages without requiring the user to click a link.

For example, to redirect the user after a successful form submission:

import { navigate } from 'vike/client/router'
 
function Form() {
   return (
     <form onSubmit={onSubmit}>
       {/* ... */}
     </form>
   )
}
 
async function onSubmit() {
  const navigationPromise = navigate('/form/success')
  console.log("The URL changed but the new page hasn't rendered yet.")
  await navigationPromise
  console.log('The new page has finished rendering.')
}

If you want to redirect the user while rendering a page then use throw redirect() instead. For example, when redirecting a non-authenticated user to a login page. See Abort > throw redirect() VS throw render() VS navigate().

If you want to programmatically navigate back then use window.history.back().

Options

  • navigate('/some-url', { keepScrollPosition: true }): Don't scroll to the top of the page, preserve the scroll position instead. See also:
  • navigate('/some-url', { overwriteLastHistoryEntry: true }): Don't create a new entry in the browser's history, instead let the new URL replace the current URL. This effectively removes the current URL from the browser history.
  • navigate('/some-url', { pageContext }): Pass extra pageContext values to the next page.

history.pushState()

If you want to change the URL completely independently of Vike then use history.pushState() instead of navigate().

// Somewhere in your client-side code
window.history.pushState(null, '', '/some-url')

You can then implement your navigation handling by listening to the popstate event.

⚠️
You must handle the popstate event, otherwise you'll break the browser's back- and forward history button.
window.addEventListener('popstate', () => {
  // Vike sets triggeredBy to 'vike' | 'browser' | 'user'
  // https://vike.dev/navigate#history-pushstate
  const { triggeredBy } = window.history.state
 
  // Navigation triggered by Vike or the browser
  if (triggeredBy === 'vike' || triggeredBy === 'browser') {
    // Abort: let Vike handle the navigation
    return
  }
 
  // Navigation triggered by our history.pushState() call
  if (triggeredBy === 'user') {
    // TODO
  }
})

Without vike-{react,vue,solid}

If you don't use a UI framework Vike extension vike-react/vike-vue/vike-solid and if you use Server Routing then use window.location.href = '/some/url' instead of navigate() (because navigate() requires Client Routing).

The UI framework Vike extensions vike-react/vike-vue/vike-solid use Client Routing.

See also