## 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' { 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. --- ## 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 opt into Client Routing. --- ## 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 : {content} })()} into any server and any deployment environment. > Alternatively, instead of using `renderPage()`, you can pre-render your pages and remove the need for a production server (and deploy to a static host instead). --- ## File: docs/components/OnlyHtmlNote.mdx import { Link } from '@brillout/docpress' It only generates `` tags while rendering the HTML of the first page the user visits: the `` 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 . --- ## File: docs/pages/abort/+Page.mdx import { Link } from '@brillout/docpress' You can use `throw render()` or `throw redirect()` 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 `throw redirect()` changes the URL, `throw render()` 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 . **`throw redirect()` VS `navigate()`** Difference between `throw redirect()` and `navigate()`: - `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 UI frameworks intercept the exception, and thus Vike doesn't catch it. Instead, consider using `throw redirect()` / `throw render()` in a Vike hook such as `guard()` or `data()`, or use `navigate()`. - **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 `renderPage()`, 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 - - - --- ## 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 ``. - `` uses `usePageContext()` to access `pageContext.urlPathname`. - `` checks whether `const isActive = href === pageContext.urlPathname` and sets a CSS class accordingly ``. Examples: - React: - 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 `ssr: false`, 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 / pre-rendering (aka SSG) 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 Server Routing or Client Routing. - 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: 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 - add a Express.js/Hono/Fastify/... server (or add Vike's server middleware if you already have one). > Example: 1. Either: - Use , or - define `+onRenderClient.js` and `+onRenderHtml.js`. > Examples: > - > - > - > - > {/* [MDX-workaround-list-at-end-of-note] */ } 1. Create your first `+Page.js` file. > Examples: > - > - > - > - > {/* [MDX-workaround-list-at-end-of-note] */ } ## See also - - - [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)