File: README.md
Vike
(Replaces Next.js/Nuxt) ๐จ Build mission-critical applications with stability and development freedom.
Links
:eyes: What is Vike: vike.dev
:clipboard: Version history & breaking changes: CHANGELOG.md
:question: Get help: vike.dev > FAQ > How can I reach out for help?
:green_heart: Contribute: CONTRIBUTING.md
Monorepo
This is the monorepo for:
| Source | Output |
|---|---|
| ./packages/vike/ | Package vike |
| ./packages/create-vike-core/ | Package create-vike-core |
| ./docs/ | Website vike.dev |
See also
| Monorepo | Output |
|---|---|
| github.com/vikejs/vike-react | Packages vike-react, vike-react-zustand, vike-react-query, ... |
| github.com/vikejs/vike-vue | Packages vike-vue, vike-vue-pinia, vike-vue-query, ... |
| github.com/vikejs/vike-solid | Packages vike-solid, vike-solid-query, ... |
File: docs/components/Advanced.mdx
import { Advanced } from '@brillout/docpress'
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:
// 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 <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 .
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
/adminandthrow redirect('/login')is called, then the/loginpage is rendered and the user sees a new URL/loginin the address bar of his browser. - If a user goes to
/adminandthrow render('/login')is called, then the/loginpage is rendered but the user keeps seeing the same URL/adminin the address bar of his browser (even though the/loginpage is rendered).
We usually recommend using
throw render()instead ofthrow 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 thusthrow 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 thethrow redirect()/throw render()exception: some other code is intercepting it and thus prevents Vike from catching it.text10:00:00 AM [vike][request(42)] throw redirect('/some-url') intercepted while rendering /some-other-urlMost 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 usingthrow redirect()/throw render()in a Vike hook such asguard()ordata(), or usenavigate(). - Make sure to use
throw redirect()/throw render()within a Vike hook.
If you usethrow 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.headersto the HTTP response.
If you've embedded Vike into your server usingrenderPage(), inspect whetherpageContext.httpResponse.headerscontains theLocationheader and then double check whether you're correctly addingpageContext.httpResponse.headersto 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
<Link>. <Link>usesusePageContext()to accesspageContext.urlPathname.<Link>checks whetherconst isActive = href === pageContext.urlPathnameand sets a CSS class accordingly<a class="is-active">.
Examples:
- React:
- Vue:
You cannot use
window.location.pathnameif you use SSR, because it isn't available when the page is rendered on the server-side.
If you have setssr: false, then you can usewindow.location.pathnameinstead ofpageContext.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 app:
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:
Add Vike to your
vite.config.js.- Example:
- Example:
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 ++] } }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:
- Enable pre-rendering, or
Either:
- Use , or
- define
+onRenderClient.jsand+onRenderHtml.js.Examples:
{/* [MDX-workaround-list-at-end-of-note] */ }
Create your first
+Page.jsfile.Examples:
{/* [MDX-workaround-list-at-end-of-note] */ }
See also
- GitHub >
vikejs/vike>examples/react-minimal - GitHub >
vikejs/vike>examples/react-full - GitHub >
vikejs/vike>examples/vue-minimal - GitHub >
vikejs/vike>examples/vue-full - GitHub >
vikejs/vike>packages/create-vike-core/boilerplate-react - GitHub >
vikejs/vike>packages/create-vike-core/boilerplate-react-ts - GitHub >
vikejs/vike>packages/create-vike-core/boilerplate-vue - GitHub >
vikejs/vike>packages/create-vike-core/boilerplate-vue-ts