## File: README.md

# Vike

(Replaces Next.js/Nuxt) 🔨 Build mission-critical applications with stability and development freedom.

## Links

:eyes: What is Vike: [vike.dev](https://vike.dev)  
:clipboard: Version history & breaking changes: [CHANGELOG.md](/packages/vike/CHANGELOG.md)  
:question: Get help: [vike.dev > FAQ > How can I reach out for help?](https://vike.dev/faq#how-can-i-reach-out-for-help)  
:green_heart: Contribute: [CONTRIBUTING.md](/CONTRIBUTING.md)  

## Monorepo

This is the [monorepo](https://en.wikipedia.org/wiki/Monorepo) for:

| Source | Output |
|-|-|
| [./packages/vike/](packages/vike/) | Package [`vike`](https://npmjs.com/package/vike) |
| [./packages/create-vike-core/](packages/create-vike-core/) | Package [`create-vike-core`](https://npmjs.com/package/create-vike-core) |
| [./docs/](docs/) | Website [vike.dev](http://vike.dev) |

## See also

| Monorepo | Output |
|-|-|
| [github.com/vikejs/vike-react](https://github.com/vikejs/vike-react) | Packages [`vike-react`](https://npmjs.com/package/vike-react), [`vike-react-zustand`](https://www.npmjs.com/package/vike-react-zustand), [`vike-react-query`](https://www.npmjs.com/package/vike-react-query), ... |
| [github.com/vikejs/vike-vue](https://github.com/vikejs/vike-vue) | Packages [`vike-vue`](https://npmjs.com/package/vike-vue), [`vike-vue-pinia`](https://www.npmjs.com/package/vike-vue-pinia), [`vike-vue-query`](https://www.npmjs.com/package/vike-vue-query), ... |
| [github.com/vikejs/vike-solid](https://github.com/vikejs/vike-solid) | Packages [`vike-solid`](https://npmjs.com/package/vike-solid), [`vike-solid-query`](https://www.npmjs.com/package/vike-solid-query), ... |

---

## File: docs/components/Advanced.mdx

import { Advanced } from '@brillout/docpress'

<Advanced>
  { props.children }
  👉
  We recommend using this advanced capability — which can be complex — only if you have a clear reason why alternatives aren't an option for you.
</Advanced>

---

## File: docs/components/DefaultRouting.mdx

import { Link } from '@brillout/docpress'
import { UiFrameworkExtension } from '../components'

> The  use Client Routing. If you don't use such Vike extension, then Vike does Server Routing by default while you can <Link href="/clientRouting">opt into Client Routing</Link>.

---

## File: docs/components/JustAMiddleware.mdx

import { Link } from '@brillout/docpress'

From the perspective of a server, Vike is just a middleware:

```ts
// server.ts

// renderPage() doesn't depend on Node.js and can be used within any JavaScript environment:
// Node.js, AWS, Cloudflare, Vercel, Deno, Bun, Lagon, ...
import { renderPage } from 'vike/server'

// Any server: Express.js, Cloudflare Worker, AWS Lambda Function, Fastify, Hono, Nitro, ...
server.addMiddleware({
  method: 'GET',
  route: '*', // catch-all
  async handler(request: Request) {
    const pageContextInit = { urlOriginal: request.url }
    const pageContext = await renderPage(pageContextInit)
    // `body` is the HTML of the page with a route matching pageContextInit.urlOriginal
    const { body, statusCode, headers } = pageContext.httpResponse
    const response = { body, statusCode, headers }
    return response
  }
})
```

You can embed {(() => {const content = `renderPage()`; return props.noLink ? content : <Link href="/renderPage">{content}</Link> })()} into any server and any deployment environment.

> Alternatively, instead of using `renderPage()`, you can <Link href="/pre-rendering">pre-render</Link> your pages and remove the need for a production server (and deploy to a <Link href="/static-hosts">static host</Link> instead).

---

## File: docs/components/OnlyHtmlNote.mdx

import { Link } from '@brillout/docpress'

It only generates `<head>` tags while rendering the HTML of the first page the user visits: the `<head>` tags aren't updated upon client-side page navigation. The reason is that it's only meant for HTML crawlers (most notably search engine bots), see explanation at <Link href="/Head#only-html" doNotInferSectionTitle />.

---

## File: docs/pages/abort/+Page.mdx

import { Link } from '@brillout/docpress'

You can use <Link href="/render">`throw render()`</Link> or <Link href="/redirect">`throw redirect()`</Link> in order to abort rendering the current page and render something else instead.


## `throw redirect()` VS `throw render()` VS `navigate()`

**`throw redirect()` VS `throw render()`**

While <Link href="/redirect">`throw redirect()`</Link> changes the URL, <Link href="/render">`throw render()`</Link> preserves it:
 - If a user goes to `/admin` and `throw redirect('/login')` is called, then the `/login` page is rendered and the user sees a new URL `/login` in the address bar of his browser.
 - If a user goes to `/admin` and `throw render('/login')` is called, then the `/login` page is rendered but the user keeps seeing the same URL `/admin` in the address bar of his browser (even though the `/login` page is rendered).

> We usually recommend using `throw render()` instead of `throw redirect()` as it preserves the URL and, therefore, the user's intention. We further explain this technique at <Link href="/auth#login-flow" />.

**`throw redirect()` VS `navigate()`**

Difference between `throw redirect()` and <Link href="/navigate">`navigate()`</Link>:
 - `navigate()` only works on the client-side and shouldn't be called during the rendering of a page.
 - `throw redirect()` works on both client- and server-side but only works during the rendering a page.

In a nutshell: if you want to abort the rendering of a page then use `throw redirect()`, otherwise use `navigate()`.

For example:
 - For redirecting the user upon a form submit action, use `navigate()`. (Since the page is already rendered and thus `throw redirect()` doesn't make sense as there is no pending page rendering to abort.)
 - For protecting a page from unprivileged access, such as a normal user trying to access an admin page, use `throw redirect()` in order to abort (on both server- and client-side) the rendering of the admin page and redirect the user to another page instead (for example the login page).


## Debug

If `throw redirect()` or `throw render()` doesn't work:
 - **Make sure `throw redirect()` / `throw render()` isn't intercepted.**  
   In development, check your server logs for the following log. If this log is missing then it means that Vike didn't catch the `throw redirect()` / `throw render()` exception: some other code is intercepting it and thus prevents Vike from catching it.
   ```
   10:00:00 AM [vike][request(42)] throw redirect('/some-url') intercepted while
   rendering /some-other-url
   ```
   > Most notably, using `throw redirect()` / `throw render()` inside a UI component usually doesn't work because most <Link href="/ui-frameworks">UI frameworks</Link> intercept the exception, and thus Vike doesn't catch it. Instead, consider using `throw redirect()` / `throw render()` in a Vike hook such as <Link href="/guard">`guard()`</Link> or <Link href="/data">`data()`</Link>, or use <Link href="/navigate">`navigate()`</Link>.
 - **Make sure to use `throw redirect()` / `throw render()` within a Vike hook.**  
   If you use `throw redirect()` / `throw render()` outside of Vike hooks, for example in some server middleware code, then Vike won't be able to intercept it.

If `throw redirect()` doesn't work:
 - **Make sure to add `pageContext.httpResponse.headers` to the HTTP response.**  
   If you've embedded Vike into your server using <Link href="/renderPage">`renderPage()`</Link>, inspect whether `pageContext.httpResponse.headers` contains [the `Location` header](https://developer.mozilla.org/en-US/docs/Web/HTTP/Reference/Headers/Location) and then double check whether you're correctly adding `pageContext.httpResponse.headers` to the HTTP response.


## See also

 - <Link href="/redirect" />
 - <Link href="/render" />
 - <Link href="/navigate" />

---

## File: docs/pages/active-links/+Page.mdx

import { RepoLink } from '@brillout/docpress'
import { Link } from '@brillout/docpress'

> **What are active links?** It's the practice of visually highlighting the current page in the navigation.
> For example, this page named "Active Links" is highlighted with a gray background in the navigation on the left of this website.
> The link is said to be "active".

To implement active links:
 - Create a new component `<Link>`.
 - `<Link>` uses <Link href="/usePageContext">`usePageContext()`</Link> to access <Link href="/pageContext">`pageContext.urlPathname`</Link>.
 - `<Link>` checks whether `const isActive = href === pageContext.urlPathname` and sets a CSS class accordingly `<a class="is-active">`.

Examples:
 - React: <RepoLink path='/packages/create-vike-core/boilerplate-react/renderer/Link.jsx' />
 - Vue: <RepoLink path='/packages/create-vike-core/boilerplate-vue/renderer/Link.vue' />

> You cannot use `window.location.pathname` if you use SSR, because it isn't available when the page is rendered on the server-side.
> If you have set <Link href="/ssr">`ssr: false`</Link>, then you can use `window.location.pathname` instead of `pageContext.urlPathname`.

---

## File: docs/pages/add/+Page.mdx

import { Link, RepoLink } from '@brillout/docpress'
import { UiFrameworkExtension } from '../../components'

The following shows how to add SSR / <Link href="/pre-rendering">pre-rendering (aka SSG)</Link> to an existing [Vite](https://vitejs.dev) app:
 - [Example of adding SSR/SSG to a Vite + React app](https://github.com/brillout/vite-to-vike)
 - [Example of adding SSR/SSG to a Vite + Vue app](https://github.com/brillout/vite-to-vike/tree/vue)

It showcases how to do so in a step-by-step, progressive, and customizable fashion:
- Choose between SSR and pre-rendering (SSG).
- With or without .
- With <Link href="/server-routing">Server Routing</Link> or <Link href="/client-routing">Client Routing</Link>.
- Progressively migrate towards the stack you (eventually) want.

You can choose whether you want to migrate towards a full-fledged SSR/SSG framework DX (like Next.js and Nuxt by using ), or add a minimal SSR/SSG implementation (applying a minimal amount of changes to your existing code), or something in-between.

This way, you can move quickly while progressively choosing your stack as you go.

On a high-level, this is how you add Vike to your existing Vite app:

1. Add Vike to your `vite.config.js`.

   - Example: <RepoLink path="/packages/create-vike-core/boilerplate-react/vite.config.js" />

1. Use Vike's CLI instead of Vite's CLI.
   ```json5
   // package.json
   {
     "scripts": {
       "dev": "vite", // [!code --]
       "dev": "vike dev", // [!code ++]
       "build": "vite build", // [!code --]
       "build": "vike build", // [!code ++]
       "preview": "vite preview", // [!code --]
       "preview": "vike preview", // [!code ++]
     }
   }
   ```

1. Either:
   - Enable pre-rendering, or
     > See <Link href="/pre-rendering" />
   - add a <Link href="/express">Express.js</Link>/<Link href="/hono">Hono</Link>/<Link href="/fastify">Fastify</Link>/<Link href="/server">...</Link> server (or add <Link href="/renderPage">Vike's server middleware</Link> if you already have one).
     > Example: <RepoLink path="/packages/create-vike-core/boilerplate-react/server/index.js" />

1. Either:
   - Use , or
   - define <Link href="/onAfterRenderClient">`+onRenderClient.js`</Link> and <Link href="/onRenderHtml">`+onRenderHtml.js`</Link>.
     > Examples:
     > - <RepoLink text="Vue" path="/packages/create-vike-core/boilerplate-vue/renderer/" />
     > - <RepoLink text="Vue + TypeScript" path="/packages/create-vike-core/boilerplate-vue-ts/renderer/" />
     > - <RepoLink text="React" path="/packages/create-vike-core/boilerplate-react/renderer/" />
     > - <RepoLink text="React + TypeScript" path="/packages/create-vike-core/boilerplate-react-ts/renderer/" />
     >  {/* [MDX-workaround-list-at-end-of-note] */ }

1. Create your first <Link href="/Page">`+Page.js`</Link> file.
   > Examples:
   > - <RepoLink text="Vue" path="/packages/create-vike-core/boilerplate-vue/pages/index/+Page.vue" />
   > - <RepoLink text="Vue + TypeScript" path="/packages/create-vike-core/boilerplate-vue-ts/pages/index/+Page.vue" />
   > - <RepoLink text="React" path="/packages/create-vike-core/boilerplate-react/pages/index/+Page.jsx" />
   > - <RepoLink text="React + TypeScript" path="/packages/create-vike-core/boilerplate-react-ts/pages/index/+Page.tsx" />
   >  {/* [MDX-workaround-list-at-end-of-note] */ }


## See also

- <Link href="/new" />
- <Link href="/new/core" />
- [GitHub > `vikejs/vike` > `examples/react-minimal`](https://github.com/vikejs/vike/tree/main/examples/react-minimal)
- [GitHub > `vikejs/vike` > `examples/react-full`](https://github.com/vikejs/vike/tree/main/examples/react-full)
- [GitHub > `vikejs/vike` > `examples/vue-minimal`](https://github.com/vikejs/vike/tree/main/examples/vue-minimal)
- [GitHub > `vikejs/vike` > `examples/vue-full`](https://github.com/vikejs/vike/tree/main/examples/vue-full)
- [GitHub > `vikejs/vike` > `packages/create-vike-core/boilerplate-react`](https://github.com/vikejs/vike/tree/main/packages/create-vike-core/boilerplate-react)
- [GitHub > `vikejs/vike` > `packages/create-vike-core/boilerplate-react-ts`](https://github.com/vikejs/vike/tree/main/packages/create-vike-core/boilerplate-react-ts)
- [GitHub > `vikejs/vike` > `packages/create-vike-core/boilerplate-vue`](https://github.com/vikejs/vike/tree/main/packages/create-vike-core/boilerplate-vue)
- [GitHub > `vikejs/vike` > `packages/create-vike-core/boilerplate-vue-ts`](https://github.com/vikejs/vike/tree/main/packages/create-vike-core/boilerplate-vue-ts)