Blitz is built on top of Next.js, so naturally follows Next's priciples and patterns. The difference between Next and Blitz is that Blitz adds all the missing features and functionality that turns Next into a true fullstack framework. That also means that you can migrate to Blitz in a few steps.
You need to replace next
dependency with blitz
.
yarn remove next ## npm uninstall next
yarn add blitz ## npm install blitz
We recommend using TypeScript (but it's not a requirement!). If you're not doing it already, you can add TypeScript with following commands:
yarn add typescript ## npm install typescript
yarn tsc init ## npx tsc init
The second command will create a tsconfig.json
file with TypeScript
configuration. Here's an example tsconfig.json
that you can use:
{
"compilerOptions": {
"target": "es5",
"lib": ["dom", "dom.iterable", "esnext"],
"baseUrl": "./",
"allowJs": true,
"skipLibCheck": true,
"strict": false,
"strictNullChecks": true,
"forceConsistentCasingInFileNames": true,
"noEmit": true,
"noUncheckedIndexedAccess": true,
"esModuleInterop": true,
"module": "esnext",
"moduleResolution": "node",
"resolveJsonModule": true,
"isolatedModules": true,
"jsx": "preserve",
"incremental": true,
"tsBuildInfoFile": ".tsbuildinfo"
},
"exclude": ["node_modules"],
"include": ["blitz-env.d.ts", "next-env.d.ts" "**/*.ts", "**/*.tsx"]
}
"allowJs": true
option will let you keep your JavaScript files so that
you don't have to migrate your application at once.
package.json
Instead of using next
to run a command, you can use blitz
. There are a
few other commands that you can find useful — read about it
here.
"scripts": {
"dev": "blitz dev",
"build": "blitz build",
"start": "blitz start"
}
As the third step, you need to rename next.config.js
to
blitz.config.ts
(or if you aren't using TypeScript, to
blitz.config.js
). To learn more about the configuration, check out the
docs.
If you want to start using Blitz's queries and
mutations, we recommend creating an app
folder and writing your application logic there. You can take a look at
the default file structure of newly generated Blitz apps.
Below, we'll cover how to setup a database, and Blitz's auth.
By default, Blitz uses Prisma which is a strongly typed database client. If you are new to databases, check out Prisma's Data Guide which covers the very large majority of everything you might want to know.
As the first step, you need to add the required dependecies:
yarn add prisma @prisma/client ## npm install prisma @prisma/client
Once this is done, you can initialize Prisma:
blitz prisma init
You can optionally pass --datasource-provider=sqlite
for a quick SQLite
database to use in your development enviroment. The default driver is
Postgres.
The init
command will create a new folder, prisma
, with a
schema.prisma
file where you can define your database models.
For Blitz to work properly, you'll need to rename the prisma
folder to
db
, and add the following to your package.json
file:
"prisma": {
"schema": "db/schema.prisma"
},
Then, you have to create a index.ts
(or index.js
) file in the db
folder. Inside we'll use enhancePrisma
function from Blitz to wrap the
Prisma's client:
// db/index.ts
import { enhancePrisma } from "blitz"
import { PrismaClient } from "@prisma/client"
const EnhancedPrisma = enhancePrisma(PrismaClient)
export * from "@prisma/client"
export default new EnhancedPrisma()
Check out our Database Overview docs to learn more about the database setup, Prisma, and some useful utilities.
In order to use Blitz's built-in auth, you need to create required
database models. Add the following code to your db/schema.prisma
file:
model User {
id Int @id @default(autoincrement())
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
name String?
email String @unique
hashedPassword String?
role String @default("USER")
tokens Token[]
sessions Session[]
}
model Session {
id Int @id @default(autoincrement())
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
expiresAt DateTime?
handle String @unique
hashedSessionToken String?
antiCSRFToken String?
publicData String?
privateData String?
user User? @relation(fields: [userId], references: [id])
userId Int?
}
model Token {
id Int @id @default(autoincrement())
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
hashedToken String
type String
expiresAt DateTime
sentTo String
user User @relation(fields: [userId], references: [id])
userId Int
@@unique([hashedToken, type])
}
Then run blitz prisma migrate dev
in your terminal to apply the changes
to your database and update Prisma client.
You also need to update your blitz.config.ts
file and add
sessionMiddleware
setup:
// blitz.config.ts
import { BlitzConfig, sessionMiddleware } from "blitz"
const config: BlitzConfig = {
middleware: [
sessionMiddleware({
cookiePrefix: "your-app-name",
}),
],
}
module.exports = config
You can take a look at our examples to see how to implement login, logout, sign up, and more, with Blitz's mutations and sessions.
Follow this documentation to setup authorization.
You can adopt Blitz incrementally by starting small and adding more pages over time. This way you can prevent derailing feature work by avoiding a complete rewrite.
The first strategy is to configure your server or proxy such that
everything under a specific subpath points to a Blitz app. For example,
your existing website might be at example.com
, and you might configure
your proxy such that example.com/store
serves a Blitz e-commerce store.
Using basePath
, you can configure your
Blitz application's assets and links to automatically work with your new
subpath /store
. Since each page in Blitz is its own
standalone route, pages like pages/products/index.tsx
will route to example.com/store/products
in your application.
// blitz.config.ts
import { BlitzConfig } from "blitz"
const config: BlitzConfig = {
basePath: "/store",
}
module.exports = config
To learn more about basePath
, take a look at our
documentation.
The second strategy is to create a new Blitz app that points to the root
URL of your domain. Then, you can use rewrites
inside
blitz.config.ts
to have some subpaths to be proxied to your existing
app.
For example, let's say you created a Blitz app to be served from
example.com
with the following blitz.config.ts
. Now, requests for the
pages you’ve added to this Blitz app (e.g. /about
if you’ve added
pages/about.tsx
) will be handled by Blitz, and requests for any other
route (e.g. /dashboard
) will be proxied to proxy.example.com
.
// blitz.config.ts
import { BlitzConfig } from "blitz"
const config: BlitzConfig = {
async rewrites() {
return {
// After checking all Blitz pages (including dynamic routes)
// and static files we proxy any other requests
fallback: [
{
source: "/:path*",
destination: `https://proxy.example.com/:path*`,
},
],
}
},
}
module.exports = config
To learn more about rewrites, take a look at our documentation.