### Install MySQL Dependencies
Source: https://github.com/nuxt-hub/core/blob/main/docs/content/docs/2.database/1.index.md
Install Drizzle ORM, Drizzle Kit, and the MySQL driver for NuxtHub.
```bash
npm install drizzle-orm drizzle-kit mysql2
```
--------------------------------
### Install SQLite Dependencies
Source: https://github.com/nuxt-hub/core/blob/main/docs/content/docs/2.database/1.index.md
Install Drizzle ORM, Drizzle Kit, and the SQLite driver for NuxtHub.
```bash
npm install drizzle-orm drizzle-kit @libsql/client
```
--------------------------------
### Install PostgreSQL Dependencies
Source: https://github.com/nuxt-hub/core/blob/main/docs/content/docs/2.database/1.index.md
Install Drizzle ORM, Drizzle Kit, and the PostgreSQL driver for NuxtHub.
```bash
npm install drizzle-orm drizzle-kit postgres @electric-sql/pglite
```
--------------------------------
### Install Dependencies and Develop NuxtHub Project
Source: https://github.com/nuxt-hub/core/blob/main/README.md
Commands for installing dependencies, preparing type stubs, developing with the playground, building, linting, and testing a NuxtHub project.
```bash
pnpm i
```
```bash
pnpm dev:prepare
```
```bash
pnpm dev
```
```bash
pnpm dev:build
```
```bash
pnpm lint
```
```bash
pnpm test
```
```bash
pnpm test:watch
```
--------------------------------
### Install VueUse Module
Source: https://github.com/nuxt-hub/core/blob/main/docs/content/docs/6.guides/2.realtime.md
Install the VueUse module using npm or yarn if you plan to use its composables, such as `useWebSocket`.
```bash
npx nuxi module add vueuse
```
--------------------------------
### Run NuxtHub Development Server
Source: https://github.com/nuxt-hub/core/blob/main/docs/content/docs/1.getting-started/2.installation.md
Navigate into your project directory and start the development server.
```bash
npm run dev
```
--------------------------------
### Client-side example for multipart upload
Source: https://github.com/nuxt-hub/core/blob/main/docs/content/docs/3.blob/2.upload.md
An example demonstrating how to perform a multipart upload from the client-side. It includes creating the upload, uploading chunks in parallel, and completing the upload. Ensure the `chunkSize` is appropriate for your needs.
```typescript
async function uploadLargeFile(file: File) {
const chunkSize = 10 * 1024 * 1024 // 10MB per part
// 1. Create the multipart upload
const { pathname, uploadId } = await $fetch(`/api/files/multipart/${file.name}`, {
method: 'POST',
})
// 2. Upload parts
const totalParts = Math.ceil(file.size / chunkSize)
const uploadedParts = []
for (let i = 0; i < totalParts; i++) {
const start = i * chunkSize
const end = Math.min(start + chunkSize, file.size)
const chunk = file.slice(start, end)
const partNumber = i + 1
const part = await $fetch(`/api/files/multipart/${pathname}`, {
method: 'PUT',
query: { uploadId, partNumber },
body: chunk,
})
uploadedParts.push(part)
console.log(`Uploaded part ${partNumber}/${totalParts}`)
}
// 3. Complete the upload
const blob = await $fetch('/api/files/multipart/complete', {
method: 'POST',
query: { pathname, uploadId },
body: uploadedParts,
})
return blob
}
```
--------------------------------
### CI/CD Workflow for D1 Migrations with Wrangler
Source: https://github.com/nuxt-hub/core/blob/main/docs/content/docs/6.guides/3.ci-cd.md
An example GitHub Actions workflow that installs dependencies, builds the Nuxt app, applies D1 migrations using Wrangler, and then deploys the application.
```yaml
jobs:
deploy:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Setup pnpm
uses: pnpm/action-setup@v6
with:
version: 11
- name: Setup Node.js
uses: actions/setup-node@v4
with:
node-version: 22
cache: pnpm
- name: Install dependencies
run: pnpm install
- name: Build
run: pnpm build
- name: Apply D1 Migrations
run: npx wrangler d1 migrations apply DB --remote --config .output/server/wrangler.json
env:
CLOUDFLARE_API_TOKEN: ${{ secrets.CLOUDFLARE_API_TOKEN }}
CLOUDFLARE_ACCOUNT_ID: ${{ secrets.CLOUDFLARE_ACCOUNT_ID }}
- name: Deploy
run: npx wrangler deploy
env:
CLOUDFLARE_API_TOKEN: ${{ secrets.CLOUDFLARE_API_TOKEN }}
CLOUDFLARE_ACCOUNT_ID: ${{ secrets.CLOUDFLARE_ACCOUNT_ID }}
```
--------------------------------
### Full Example: Server and Client File Upload
Source: https://github.com/nuxt-hub/core/blob/main/docs/content/docs/3.blob/2.upload.md
A complete example demonstrating file uploads using both server-side API routes and client-side Vue composables. The server validates image uploads up to 10MB and prefixes them with 'avatars', while the client handles user interaction and displays upload status.
```typescript
import { blob } from 'hub:blob'
export default eventHandler(async (event) => {
return blob.handleUpload(event, {
formKey: 'files',
multiple: true,
ensure: {
maxSize: '10MB',
types: ['image'],
},
put: {
addRandomSuffix: true,
prefix: 'avatars',
},
})
})
```
```vue
```
--------------------------------
### Install Nightly Build of NuxtHub
Source: https://github.com/nuxt-hub/core/blob/main/docs/content/docs/1.getting-started/2.installation.md
To use the latest features and fixes, install the nightly build of @nuxthub/core by referencing the 'nightly' tag in your package.json.
```json
{
"Dependencies": {
- "@nuxthub/core": "^1.0.0"
+ "@nuxthub/core": "npm:@nuxthub/core@nightly"
}
}
```
--------------------------------
### Install Nuxt Image Module
Source: https://github.com/nuxt-hub/core/blob/main/docs/content/docs/3.blob/1.index.md
Install the `@nuxt/image` module using the Nuxt CLI. This command automatically adds the module to your `nuxt.config.ts`.
```bash
npx nuxt module add image
```
--------------------------------
### Deploy Local NuxtHub Project
Source: https://github.com/nuxt-hub/core/blob/main/docs/content/docs/1.getting-started/3.deploy.md
Use this command to deploy your local Nuxt project. It handles login, Cloudflare linking, project setup, building, and deployment.
```bash
npx nuxthub deploy
```
--------------------------------
### Install Vercel Dependencies for NuxtHub
Source: https://github.com/nuxt-hub/core/blob/main/docs/content/docs/1.getting-started/4.migration.md
Install necessary npm packages for Vercel deployment, including support for blob storage, KV/Cache with Upstash Redis, and PostgreSQL.
```bash
# For blob storage
npm install @vercel/blob
# For KV/Cache (Upstash Redis)
npm install @upstash/redis
# For PostgreSQL database
npm install drizzle-orm drizzle-kit postgres @electric-sql/pglite
```
--------------------------------
### Create Users Table Migration
Source: https://github.com/nuxt-hub/core/blob/main/docs/content/docs/2.database/4.migrations.md
An example SQL migration file to create a 'users' table. This file would be placed in one of the configured migration directories.
```sql
CREATE TABLE IF NOT EXISTS users (
id INTEGER PRIMARY KEY,
name TEXT NOT NULL,
email TEXT NOT NULL
);
```
--------------------------------
### Get blob body
Source: https://github.com/nuxt-hub/core/blob/main/docs/content/docs/3.blob/3.usage.md
This example shows server code to get a blob's content by its pathname and convert it to text or buffer.
```APIDOC
## GET /files/[...pathname]
### Description
Retrieves the content of a specific blob.
### Method
GET
### Endpoint
`/files/[...pathname]`
### Parameters
#### Path Parameters
- **pathname** (String) - Required - The pathname of the blob.
### Return
Returns a [`Blob`](https://developer.mozilla.org/en-US/docs/Web/API/Blob) or `null` if not found.
### Request Example
```ts
const file = await blob.get('documents/report.pdf')
if (file) {
const text = await file.text()
// or: const buffer = await file.arrayBuffer()
}
```
```
--------------------------------
### Simple Upload API Route
Source: https://github.com/nuxt-hub/core/blob/main/docs/content/docs/3.blob/2.upload.md
This example creates an API route to handle file uploads on `/api/upload`. It validates the files to be images of less than 10MB, and uploads them to Blob Storage with a random suffix and the `images` prefix.
```APIDOC
## POST /api/upload
### Description
Handles file uploads, validating them against specified criteria and uploading to Blob Storage.
### Method
POST
### Endpoint
/api/upload
### Parameters
#### Request Body
- **files** (File/FileList) - Required - The file(s) to upload.
### Request Example
```ts
// In server/api/upload.post.ts
import { blob } from 'hub:blob'
export default eventHandler(async (event) => {
return blob.handleUpload(event, {
formKey: 'files',
multiple: true,
ensure: {
maxSize: '10MB',
types: ['image/jpeg', 'image/png', 'image/webp'],
},
put: {
addRandomSuffix: true,
prefix: 'images',
},
})
})
```
### Response
#### Success Response (200)
- **BlobObject[]** - An array of uploaded blob objects if `multiple` is true, otherwise a single `BlobObject`.
#### Response Example
```json
[
{
"key": "images/random-suffix.jpg",
"url": "https://your-blob-storage.com/images/random-suffix.jpg"
}
]
```
```
--------------------------------
### Get blob metadata
Source: https://github.com/nuxt-hub/core/blob/main/docs/content/docs/3.blob/3.usage.md
This example creates an API route to get a blob's metadata by its pathname.
```APIDOC
## GET /files/[...pathname]
### Description
Retrieves the metadata for a specific blob without fetching its content.
### Method
GET
### Endpoint
`/files/[...pathname]`
### Parameters
#### Path Parameters
- **pathname** (String) - Required - The pathname of the blob.
### Response
#### Success Response (200)
- **pathname** (string) - The pathname of the blob.
- **contentType** (string | undefined) - The content type of the blob.
- **size** (number) - The size of the blob in bytes.
- **httpEtag** (string | undefined) - The HTTP ETag of the blob.
- **uploadedAt** (Date) - The date and time when the blob was uploaded.
- **httpMetadata** (Record) - HTTP metadata associated with the blob.
- **customMetadata** (Record) - Custom metadata stored with the blob.
- **url** (string | undefined) - The URL of the blob if accessible.
### Response Example
```json
{
"pathname": "images/avatar.png",
"contentType": "image/png",
"size": 1024,
"httpEtag": "abcdef12345",
"uploadedAt": "2023-10-27T10:00:00.000Z",
"httpMetadata": {},
"customMetadata": {},
"url": "https://example.com/files/images/avatar.png"
}
```
```
--------------------------------
### Upload a blob
Source: https://github.com/nuxt-hub/core/blob/main/docs/content/docs/3.blob/3.usage.md
This example creates an API route to upload an image with a maximum size of 1MB to the Blob storage.
```APIDOC
## POST /files
### Description
Uploads a blob to the Blob storage.
### Method
POST
### Endpoint
`/files`
### Parameters
#### Request Body
- **file** (File) - Required - The file to upload.
- **options** (Object) - Optional - Options for the upload.
- **access** (String) - Optional - The access level of the blob ('public' or 'private'). Only supported by S3 driver.
- **contentType** (String) - Optional - The content type of the blob. Inferred if not provided.
- **contentLength** (String) - Optional - The content length of the blob.
- **addRandomSuffix** (Boolean) - Optional - If true, a random suffix is added to the blob's pathname. Defaults to false.
- **prefix** (String) - Optional - A prefix to add to the blob's pathname.
- **customMetadata** (Record) - Optional - Custom metadata to store with the blob (not supported in Vercel Blob driver).
### Request Example
```ts
// Upload from a File object
const file = document.querySelector('input[type="file"]')?.files?.[0]
if (file) {
await blob.put('images/1.jpg', file)
}
// Upload with options
await blob.put(file.name, file, {
access: 'public',
addRandomSuffix: true,
prefix: 'images/',
customMetadata: {
userId: '123',
category: 'reports'
}
})
// Upload from a URL
const response = await fetch('https://example.com/image.png')
const imageBlob = await response.blob()
await blob.put('downloads/image.png', imageBlob)
// Upload to a specific folder
await blob.put('avatar.png', file, {
prefix: `users/${userId}`
})
```
### Response
#### Success Response (200)
- **pathname** (string) - The pathname of the blob.
- **contentType** (string | undefined) - The content type of the blob.
- **size** (number) - The size of the blob in bytes.
- **httpEtag** (string | undefined) - The HTTP ETag of the blob.
- **uploadedAt** (Date) - The date and time when the blob was uploaded.
- **httpMetadata** (Record) - HTTP metadata associated with the blob.
- **customMetadata** (Record) - Custom metadata stored with the blob.
- **url** (string | undefined) - The URL of the blob if accessible.
### Response Example
```json
{
"pathname": "images/1.jpg",
"contentType": "image/jpeg",
"size": 1048576,
"httpEtag": "xyz789",
"uploadedAt": "2023-10-27T11:00:00.000Z",
"httpMetadata": {},
"customMetadata": {},
"url": "https://example.com/files/images/1.jpg"
}
```
```
--------------------------------
### List Blobs with Prefix
Source: https://github.com/nuxt-hub/core/blob/main/docs/content/docs/3.blob/3.usage.md
Filter blobs by a prefix to organize files into directories. This example lists all files within the 'images/' directory.
```typescript
// List all files in the "images/" directory
const { blobs } = await blob.list({ prefix: 'images/' })
```
--------------------------------
### Apply D1 Migrations with Nuxt CLI
Source: https://github.com/nuxt-hub/core/blob/main/docs/content/docs/6.guides/3.ci-cd.md
An example GitHub Actions step to apply D1 migrations using the Nuxt CLI's `db migrate` command. This method requires D1 HTTP credentials to be configured.
```yaml
- name: Apply D1 Migrations
run: npx nuxt db migrate
env:
NUXT_HUB_CLOUDFLARE_ACCOUNT_ID: ${{ secrets.CLOUDFLARE_ACCOUNT_ID }}
NUXT_HUB_CLOUDFLARE_API_TOKEN: ${{ secrets.CLOUDFLARE_API_TOKEN }}
NUXT_HUB_CLOUDFLARE_DATABASE_ID: ${{ secrets.CLOUDFLARE_DATABASE_ID }}
```
--------------------------------
### Default NuxtHub Deployment Workflow (pnpm)
Source: https://github.com/nuxt-hub/core/blob/main/docs/content/docs/1.getting-started/3.deploy.md
This is the default GitHub Actions workflow for deploying to NuxtHub, configured for a project using pnpm. It checks out the code, sets up Node.js and pnpm, installs dependencies, and then uses the NuxtHub action for deployment.
```yaml
name: Deploy to NuxtHub
on: push
jobs:
deploy:
name: "Deploy to NuxtHub"
runs-on: ubuntu-latest
permissions:
contents: read
id-token: write
steps:
- uses: actions/checkout@v6
- name: Install pnpm
uses: pnpm/action-setup@v6
with:
version: 11
- name: Install Node.js
uses: actions/setup-node@v6
with:
node-version: 24
cache: 'pnpm'
- name: Install dependencies
run: pnpm install
- name: Build & Deploy to NuxtHub
uses: nuxt-hub/action@v2
```
--------------------------------
### Generate Cache Key Example
Source: https://github.com/nuxt-hub/core/blob/main/docs/content/docs/5.cache/2.usage.md
Demonstrates the default cache key generation pattern for cached functions and handlers, combining group, name, and a generated key.
```typescript
const getAccessToken = defineCachedFunction(() => {
return String(Date.now())
}, {
maxAge: 60,
name: 'getAccessToken',
getKey: () => 'default'
})
```
--------------------------------
### GitHub Actions Workflow for Cloudflare Deployment
Source: https://github.com/nuxt-hub/core/blob/main/docs/content/docs/6.guides/3.ci-cd.md
This GitHub Actions workflow automates the deployment of a NuxtHub application to Cloudflare. It handles dependency installation, building the application, and deploying using Wrangler, with environment variable configuration for different deployment stages.
```yaml
name: Deploy to Cloudflare
on:
push:
branches: [main]
pull_request:
branches: [main]
jobs:
deploy:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Setup pnpm
uses: pnpm/action-setup@v6
with:
version: 11
- name: Setup Node.js
uses: actions/setup-node@v4
with:
node-version: 22
cache: pnpm
- name: Install dependencies
run: pnpm install
- name: Build
run: pnpm build
env:
CLOUDFLARE_ENV: ${{ github.ref == 'refs/heads/main' && '' || 'preview' }}
- name: Deploy
run: npx wrangler deploy
env:
CLOUDFLARE_API_TOKEN: ${{ secrets.CLOUDFLARE_API_TOKEN }}
```
--------------------------------
### Seed Admin User Post-Migration Query
Source: https://github.com/nuxt-hub/core/blob/main/docs/content/docs/2.database/4.migrations.md
An example SQL query to insert or ignore an admin user. This query runs after migrations and should be idempotent.
```sql
INSERT OR IGNORE INTO admin_users (id, email, password_hash)
VALUES (1, '', '');
```
--------------------------------
### List Keys with a Specific Prefix
Source: https://github.com/nuxt-hub/core/blob/main/docs/content/docs/4.kv/2.usage.md
Retrieves an array of keys that start with a specified prefix. This allows for filtering keys based on organizational patterns.
```typescript
import { kv } from '@nuxthub/kv'
const vueKeys = await kv.keys('vue')
/*
[
'vue:nuxt',
'vue:quasar'
]
*/
```
--------------------------------
### Add Post-Migration Queries Path via Hook
Source: https://github.com/nuxt-hub/core/blob/main/docs/content/docs/2.database/4.migrations.md
Use the `hub:db:queries:paths` hook to specify additional SQL files that should be executed after migrations. This is useful for seeding data or running setup queries.
```typescript
import { createResolver, defineNuxtModule } from '@nuxt/kit'
export default defineNuxtModule({
meta: {
name: 'my-auth-module'
},
setup(options, nuxt) {
const { resolve } = createResolver(import.meta.url)
nuxt.hook('hub:db:queries:paths', (paths, dialect) => {
paths.push(resolve(`./db-queries/seed-admin.${dialect}.sql`))
})
}
})
```
--------------------------------
### Example of Automatic Cache Key Normalization
Source: https://github.com/nuxt-hub/core/blob/main/docs/content/docs/5.cache/2.usage.md
Demonstrates how a route path is transformed into a normalized cache key by Nitro's internal utility. This process removes characters like '/' and '-' to ensure compatibility with various storage backends.
```typescript
getKey: () => '/api/products/sale-items'
```
```plaintext
api/productssaleitems.json
```
--------------------------------
### Create New NuxtHub Project
Source: https://github.com/nuxt-hub/core/blob/main/docs/content/docs/1.getting-started/2.installation.md
Use this command to initialize a new NuxtHub project with the 'hello-edge' template.
```bash
npx nuxthub init my-app
```
--------------------------------
### Importing KV Storage
Source: https://github.com/nuxt-hub/core/blob/main/docs/content/docs/4.kv/2.usage.md
Demonstrates the recommended way to import the KV storage using `@nuxthub/kv`, which is compatible with Nuxt and external bundlers.
```APIDOC
## Importing the KV storage
### Recommended: `@nuxthub/kv`
Use `@nuxthub/kv` to import the KV storage. This works everywhere, including in Nuxt server routes and external bundlers like [Workflow](https://useworkflow.dev):
```ts
import { kv } from '@nuxthub/kv'
```
::tip{icon="i-lucide-sparkles"}
This is the **recommended approach** as it works with both Nuxt and external tools that bundle your code independently.
::
### Legacy: `hub:kv`
The virtual module `hub:kv` is still supported for backwards compatibility (Nuxt only):
```ts
import { kv } from 'hub:kv'
```
::tip
`kv` is auto-imported on the server-side, so you can use it directly without importing.
::
```
--------------------------------
### Get Blob Content with `get()`
Source: https://github.com/nuxt-hub/core/blob/main/docs/content/docs/3.blob/3.usage.md
Retrieve a blob's content as a `Blob` object. The content can then be processed as text or an ArrayBuffer. Returns `null` if the blob is not found.
```typescript
const file = await blob.get('documents/report.pdf')
if (file) {
const text = await file.text()
// or: const buffer = await file.arrayBuffer()
}
```
```typescript
const file = await blob.get('documents/report.pdf')
```
--------------------------------
### Creating Cloudflare KV Namespaces
Source: https://github.com/nuxt-hub/core/blob/main/docs/content/docs/1.getting-started/5.environments.md
Create KV namespaces for each environment, specifying the environment with the --env flag.
```bash
wrangler kv namespace create KV
wrangler kv namespace create KV --env preview
wrangler kv namespace create KV --env staging
```
--------------------------------
### Get an Item
Source: https://github.com/nuxt-hub/core/blob/main/docs/content/docs/4.kv/2.usage.md
Retrieves a value from the KV storage using its key.
```APIDOC
## Get an item
Retrieves an item from the Key-Value storage.
```ts
import { kv } from '@nuxthub/kv'
const vue = await kv.get('vue')
/*
{
year: 2014
}
*/
```
```
--------------------------------
### Creating Cloudflare D1 Databases
Source: https://github.com/nuxt-hub/core/blob/main/docs/content/docs/1.getting-started/5.environments.md
Create separate D1 databases for each environment using the Wrangler CLI.
```bash
wrangler d1 create my-app-production
wrangler d1 create my-app-preview
wrangler d1 create my-app-staging
```
--------------------------------
### Clear KV Namespace by Prefix
Source: https://github.com/nuxt-hub/core/blob/main/docs/content/docs/4.kv/2.usage.md
Deletes all items that start with a specific prefix within the KV namespace. This is useful for targeted cleanup.
```typescript
import { kv } from '@nuxthub/kv'
await kv.clear('react')
```
--------------------------------
### Migrate Database Directory Structure
Source: https://github.com/nuxt-hub/core/blob/main/docs/content/docs/1.getting-started/4.migration.md
Move database schema and migration files from `server/database/` to `server/db/`.
```bash
# Move schema files
mv server/database/schema.ts server/db/schema.ts
# Move migrations
mv server/database/migrations/ server/db/migrations/
```
--------------------------------
### Add NuxtHub Module to Nuxt Project
Source: https://github.com/nuxt-hub/core/blob/main/docs/content/docs/1.getting-started/2.installation.md
Install the NuxtHub module to your existing Nuxt project. This command adds the dependency and configures it in your nuxt.config.ts.
```bash
npx nuxi module add hub
```
--------------------------------
### Get an Item from KV Storage
Source: https://github.com/nuxt-hub/core/blob/main/docs/content/docs/4.kv/2.usage.md
Retrieves a value from the Key-Value storage using its key. The retrieved value will be the JavaScript object previously stored.
```typescript
import { kv } from '@nuxthub/kv'
const vue = await kv.get('vue')
/*
{
year: 2014
}
*/
```
--------------------------------
### Configure PostgreSQL Read Replicas
Source: https://github.com/nuxt-hub/core/blob/main/docs/content/docs/2.database/1.index.md
Configures PostgreSQL read replicas by providing an array of database URLs. Read queries are routed to replicas, while write queries go to the primary.
```typescript
export default defineNuxtConfig({
hub: {
db: {
dialect: 'postgresql',
replicas: [
process.env.DATABASE_URL_REPLICA_1,
process.env.DATABASE_URL_REPLICA_2
].filter(Boolean)
}
}
})
```
--------------------------------
### Creating Cloudflare R2 Buckets
Source: https://github.com/nuxt-hub/core/blob/main/docs/content/docs/1.getting-started/5.environments.md
Create separate R2 buckets for each environment using the Wrangler CLI.
```bash
wrangler r2 bucket create my-app-production
wrangler r2 bucket create my-app-preview
wrangler r2 bucket create my-app-staging
```
--------------------------------
### Manage Database with `nuxt db` CLI
Source: https://github.com/nuxt-hub/core/blob/main/docs/content/changelog/nuxthub-multi-vendor.md
Utilize the `nuxt db` CLI for database management tasks, including generating migrations, applying them, running SQL queries, marking migrations as applied, and dropping tables. Migrations are automatically applied during development and build.
```bash
# Generate migrations from schema changes
npx nuxt db generate
# Apply migrations
npx nuxt db migrate
# Run SQL queries directly
npx nuxt db sql "SELECT * FROM users"
# Mark migrations as applied
npx nuxt db mark-as-migrated
# Drop a table
npx nuxt db drop
```
--------------------------------
### SQL UPDATE Query
Source: https://github.com/nuxt-hub/core/blob/main/docs/content/docs/2.database/3.query.md
Update existing records in the users table. Use `.where()` to specify which rows to update and `.returning()` to get the updated rows.
```typescript
import { db, schema } from '@nuxthub/db'
export default eventHandler(async (event) => {
const { id } = getRouterParams(event)
const { name } = await readBody(event)
return await db
.update(schema.users)
.set({ name })
.where(eq(tables.users.id, Number(id)))
.returning()
})
```
--------------------------------
### Generate Database Migrations
Source: https://github.com/nuxt-hub/core/blob/main/docs/content/docs/2.database/1.index.md
Generate SQL migration files from your database schema using the Nuxt DB command.
```bash
npx nuxt db generate
```
--------------------------------
### Deleting Blobs
Source: https://github.com/nuxt-hub/core/blob/main/docs/content/docs/3.blob/3.usage.md
Demonstrates how to delete single or multiple blob objects from storage using the `blob.del()` method. An example API route is also provided.
```APIDOC
## `blob.del()`
### Description
The `del()` method deletes one or multiple blob objects from the Blob storage.
You can also delete multiple blobs at once:
```ts
await blob.del('images/1.jpg')
await blob.del(['images/1.jpg', 'images/2.jpg', 'images/3.jpg'])
```
::note
You can also use `delete()` as an alias for `del()`.
::
#### Params
::field-group
::field{name="pathname" type="String | String[]" required}
The pathname(s) of the blob(s) to delete.
::
::
#### Return
Returns nothing.
```
--------------------------------
### Generate Database Migrations
Source: https://github.com/nuxt-hub/core/blob/main/docs/content/docs/2.database/cli.md
Generates database migration files based on schema changes. Use `--name` to specify a custom name and `--custom` to create an empty file for manual SQL.
```bash
npx nuxt db generate
```
```bash
npx nuxt db generate --name add_new_column
```
```bash
npx nuxt db generate --custom --name seed_initial_data
```
--------------------------------
### List Blobs in API Route
Source: https://github.com/nuxt-hub/core/blob/main/docs/content/docs/3.blob/3.usage.md
Create an API route to list the first 10 blobs in Blob storage. The `limit` option is ignored when using the local filesystem driver.
```typescript
export default eventHandler(async () => {
const { blobs } = await blob.list({ limit: 10 })
return blobs
})
```
--------------------------------
### TypeScript Schema with Auto-Casing
Source: https://github.com/nuxt-hub/core/blob/main/docs/content/docs/2.database/1.index.md
Example of a TypeScript schema using camelCase for model properties, which will be automatically mapped to snake_case in a PostgreSQL database when the 'casing' option is set to 'snake_case'.
```typescript
import { pgTable, text, serial, timestamp } from 'drizzle-orm/pg-core'
export const users = pgTable('users', {
id: serial().primaryKey(),
firstName: text().notNull(), // Maps to first_name in the database
lastName: text().notNull(), // Maps to last_name in the database
createdAt: timestamp().notNull().default(sql`CURRENT_TIMESTAMP`) // Maps to created_at
})
```
--------------------------------
### Get Blob Metadata with `head()`
Source: https://github.com/nuxt-hub/core/blob/main/docs/content/docs/3.blob/3.usage.md
Fetch a blob's metadata without downloading its content. Useful for checking file properties like size, content type, and upload date.
```typescript
await blob.head('images/avatar.png')
// { pathname, contentType, size, uploadedAt, ... }
```
--------------------------------
### Creating Specific Database Types with Pick and Omit
Source: https://github.com/nuxt-hub/core/blob/main/docs/content/docs/2.database/2.schema.md
Shows how to create more granular types for specific use cases, such as a public-facing user type or a type for user creation forms, by leveraging TypeScript's utility types.
```typescript
// User without password for public API responses
export type PublicUser = Omit
// Only the fields needed for user creation form
export type UserForm = Pick
```
--------------------------------
### Get Blob Metadata via API Route
Source: https://github.com/nuxt-hub/core/blob/main/docs/content/docs/3.blob/3.usage.md
Create an API route to retrieve a blob's metadata using its pathname. This route uses `blob.head()` to fetch metadata without downloading the content.
```typescript
import { blob } from '@nuxthub/blob'
import { eventHandler, getRouterParams } from 'h3'
export default eventHandler(async (event) => {
const { pathname } = getRouterParams(event)
return blob.head(pathname)
})
```
--------------------------------
### Pre-render Dynamic Pages with a Nuxt Module
Source: https://github.com/nuxt-hub/core/blob/main/docs/content/docs/6.guides/1.pre-rendering.md
Implement a local Nuxt module to pre-render dynamic pages. This approach is beneficial when you need to pre-render specific routes that don't follow a simple pattern, such as `/page-1` or `/parent/page-2`.
```typescript
import { defineNuxtModule, addPrerenderRoutes } from '@nuxt/kit'
export default defineNuxtModule({
meta: {
name: 'nuxt-prerender-routes',
},
async setup() {
const pages = await getDynamicPages()
addPrerenderRoutes(pages)
},
})
async function getDynamicPages(): string[] {
// Replace this function with the logic for retrieving the slugs for your pages.
return ['/page-1', '/parent/page-2']
}
```
--------------------------------
### Cleanup Inactive Users with Workflow
Source: https://github.com/nuxt-hub/core/blob/main/docs/content/docs/2.database/3.query.md
Example of using `@nuxthub/db` within a Workflow task to delete users who haven't logged in for a specified period. It uses `drizzle-orm`'s `lt` operator for date comparison.
```typescript
import { db, schema } from '@nuxthub/db'
import { lt } from 'drizzle-orm'
export default async function cleanupInactiveUsers() {
// Delete users who haven't logged in for 90 days
const ninetyDaysAgo = new Date(Date.now() - 90 * 24 * 60 * 60 * 1000)
const deleted = await db
.delete(schema.users)
.where(lt(schema.users.lastLoginAt, ninetyDaysAgo))
.returning()
return {
deletedCount: deleted.length,
deletedUserIds: deleted.map(u => u.id)
}
}
```
--------------------------------
### GitLab CI Configuration for NuxtHub Deployment
Source: https://github.com/nuxt-hub/core/blob/main/docs/content/docs/1.getting-started/3.deploy.md
This configuration sets up a GitLab CI pipeline for deploying NuxtHub projects. It includes stages for deployment and callbacks, with rules for automatic deployment on 'staging' and 'main' branches, and a manual trigger for other branches. Ensure `NUXT_HUB_PROJECT_KEY` and `NUXT_HUB_USER_TOKEN` are set as CI/CD variables.
```yaml
# if one job fails, pipeline should fail
workflow:
auto_cancel:
on_job_failure: all
variables:
APP_PATH: "PATH/TO/YOUR/APP"
NUXT_HUB_PROJECT_KEY: "YOUR_NUXT_HUB_PROJECT_KEY"
# add additional steps as needed
stages:
- deploy
- callback
deploy_project:
stage: deploy
# here we use Bun, you can change this.
image: "oven/bun:slim"
script:
- echo "Deploying project_a app..."
- cd $APP_PATH
# you can not use node_modules from cache, since nuxthub needs write access
- bun install
# if you set up your variables correctly this should deploy successfully
- bunx nuxthub deploy
rules:
# here we configure auto deploy on branch: staging and main
- if: '$CI_COMMIT_BRANCH == "staging" || $CI_COMMIT_BRANCH == "main"'
manual_deploy_project:
stage: deploy
image: "oven/bun:slim"
when: manual
script:
- echo "Deploying project_a app..."
- cd $APP_PATH
- bun install
- bunx nuxthub deploy
callback:
stage: callback
script:
- echo "Deploy reached."
```
--------------------------------
### Abort a multipart upload
Source: https://github.com/nuxt-hub/core/blob/main/docs/content/docs/3.blob/2.upload.md
Aborts an ongoing multipart upload. This operation requires the pathname and upload ID to identify the upload to be cancelled. The `blob.resumeMultipartUpload` function is used to get the multipart upload object, and its `abort` method is called.
```typescript
import { blob } from 'hub:blob'
export default eventHandler(async (event) => {
const { pathname } = getRouterParams(event)
const { uploadId } = getQuery(event)
const mpu = blob.resumeMultipartUpload(pathname, uploadId as string)
await mpu.abort()
return sendNoContent(event)
})
```
--------------------------------
### Configure MySQL Read Replicas
Source: https://github.com/nuxt-hub/core/blob/main/docs/content/docs/2.database/1.index.md
Configures MySQL read replicas by providing an array of database URLs. Read queries are routed to replicas, while write queries go to the primary.
```typescript
export default defineNuxtConfig({
hub: {
db: {
dialect: 'mysql',
replicas: [
process.env.DATABASE_URL_REPLICA_1,
process.env.DATABASE_URL_REPLICA_2
].filter(Boolean)
}
}
})
```
--------------------------------
### List Blobs
Source: https://github.com/nuxt-hub/core/blob/main/docs/content/docs/3.blob/3.usage.md
This operation retrieves a paginated list of blobs from the storage. You can filter results by prefix, control the number of items returned, and use cursors for pagination. It also supports a 'folded' option to get a folder-like structure.
```APIDOC
## list()
### Description
Returns a paginated list of blobs (metadata only).
### Method
```ts
await blob.list(options)
```
### Parameters
#### Options Object
- **limit** (Number) - Optional - The maximum number of blobs to return per request. Defaults to `1000`.
- **prefix** (String) - Optional - Filters the results to only those that begin with the specified prefix.
- **cursor** (String) - Optional - The cursor to continue from a previous list operation.
- **folded** (Boolean) - Optional - If `true`, the list will be folded using `/` separator and list of folders will be returned.
### Return
Returns a JSON object with the following structure:
```json
{
"blobs": [
{
"pathname": "string",
"contentType": "string | undefined",
"size": "number",
"httpEtag": "string | undefined",
"uploadedAt": "Date",
"httpMetadata": "Record",
"customMetadata": "Record",
"url": "string | undefined"
}
],
"hasMore": "boolean",
"cursor": "string | undefined",
"folders": "string[] | undefined"
}
```
### Examples
#### List with prefix
```ts
// List all files in the "images/" directory
const { blobs } = await blob.list({ prefix: 'images/' })
```
#### List with folders
```ts
const { blobs, folders } = await blob.list({ folded: true })
// folders: ['images/', 'documents/', 'videos/']
```
#### Pagination
```ts
let allBlobs = []
let cursor = null
do {
const result = await blob.list({ cursor })
allBlobs.push(...result.blobs)
cursor = result.cursor
} while (cursor)
```
```
--------------------------------
### Expose Blobs on a Server Route
Source: https://github.com/nuxt-hub/core/blob/main/docs/content/docs/3.blob/1.index.md
Create a server route to serve blobs using `blob.serve()`. This route should handle requests for images and pass them to the blob serving function. This is essential for providers like Cloudflare and Vercel to optimize image URLs.
```typescript
import { blob } from 'hub:blob'
import { createError, eventHandler, getRouterParam } from 'h3'
export default eventHandler(async (event) => {
const pathname = getRouterParam(event, 'pathname')
if (!pathname) {
throw createError({ statusCode: 404, statusMessage: 'Not Found' })
}
return blob.serve(event, pathname)
})
```
--------------------------------
### Apply Database Migrations
Source: https://github.com/nuxt-hub/core/blob/main/docs/content/docs/2.database/4.migrations.md
Command to apply generated migration files to the database. This is typically done manually or as part of a deployment process.
```bash
npx nuxt db migrate
```
--------------------------------
### Configure Environment-Specific Bindings in wrangler.jsonc
Source: https://github.com/nuxt-hub/core/blob/main/docs/content/docs/1.getting-started/3.deploy.md
Define production and preview environment bindings for D1 databases in your wrangler.jsonc file. Ensure non-inheritable keys like d1_databases are specified explicitly for each environment to avoid runtime errors.
```jsonc
{
"$schema": "node_modules/wrangler/config-schema.json",
// Production bindings (top-level)
"d1_databases": [
{
"binding": "DB",
"database_id": ""
}
],
// Preview environment
"env": {
"preview": {
"d1_databases": [
{
"binding": "DB",
"database_id": ""
}
]
}
}
}
```
--------------------------------
### Deploy NuxtHub Project in CI/CD
Source: https://github.com/nuxt-hub/core/blob/main/docs/content/docs/1.getting-started/3.deploy.md
Deploy your NuxtHub project non-interactively in CI/CD pipelines by setting the `NUXT_HUB_PROJECT_KEY` and `NUXT_HUB_USER_TOKEN` environment variables. This ensures automatic authentication and deployment.
```bash
NUXT_HUB_PROJECT_KEY= NUXT_HUB_USER_TOKEN= npx nuxthub deploy
```
--------------------------------
### Configure Blob Driver in Nuxt Config
Source: https://github.com/nuxt-hub/core/blob/main/docs/content/docs/3.blob/1.index.md
Set a custom driver for blob storage in your `nuxt.config.ts`. You can specify the driver type and its specific configuration options. This example shows setting the 'fs' driver with a custom directory and overwriting it with 'vercel-blob' in production.
```typescript
export default defineNuxtConfig({
hub: {
blob: {
driver: 'fs',
dir: '.data/blob'
}
},
// or overwrite only in production
$production: {
hub: {
blob: {
driver: 'vercel-blob'
}
}
}
})
```
--------------------------------
### Configure NuxtHub for Multi-Vendor Deployments
Source: https://github.com/nuxt-hub/core/blob/main/docs/content/changelog/nuxthub-multi-vendor.md
Configure database, blob, KV, and cache drivers in `nuxt.config.ts`. NuxtHub automatically detects and configures the appropriate drivers based on your deployment environment. It uses PGLite locally if no PostgreSQL connection is provided.
```typescript
export default defineNuxtConfig({
hub: {
db: 'postgresql', // or 'sqlite', 'mysql'
blob: true,
kv: true,
cache: true
}
})
```
--------------------------------
### Upload a part to a multipart upload
Source: https://github.com/nuxt-hub/core/blob/main/docs/content/docs/3.blob/2.upload.md
Resumes an existing multipart upload and uploads a single part. Requires the pathname, upload ID, part number, and the body of the part. The `blob.resumeMultipartUpload` function is used to get a `BlobMultipartUpload` object, which then has the `uploadPart` method called on it.
```typescript
import { blob } from 'hub:blob'
export default eventHandler(async (event) => {
const { pathname } = getRouterParams(event)
const { uploadId, partNumber } = getQuery(event)
const body = await readRawBody(event)
const mpu = blob.resumeMultipartUpload(pathname, uploadId as string)
return mpu.uploadPart(Number(partNumber), body)
})
```
--------------------------------
### Using Shared Database Types in Vue and API
Source: https://github.com/nuxt-hub/core/blob/main/docs/content/docs/2.database/2.schema.md
Demonstrates how to fetch data using the shared User type in a Vue component and how to insert new users using the NewUser type in an API route.
```vue
```
```typescript
import { db, schema } from '@nuxthub/db'
export default eventHandler(async (event) => {
const body = await readBody(event)
return await db.insert(schema.users).values(body).returning()
})
```
--------------------------------
### List All Keys
Source: https://github.com/nuxt-hub/core/blob/main/docs/content/docs/4.kv/2.usage.md
Retrieves all keys present in the KV storage. Supports filtering keys by a specific prefix.
```APIDOC
## List all keys
Retrieves all keys from the KV storage.
```ts
import { kv } from '@nuxthub/kv'
const keys = await kv.keys()
/*
[
'react',
'react:gatsby',
'react:next',
'vue',
'vue:nuxt',
'vue:quasar'
]
```
To get the keys starting with a specific prefix, you can pass the prefix as an argument. We recommend using prefixes for better organization in your KV namespace.
```ts
import { kv } from '@nuxthub/kv'
const vueKeys = await kv.keys('vue')
/*
[
'vue:nuxt',
'vue:quasar'
]
*/
```
```
--------------------------------
### Dedicated Migration Job in GitHub Actions
Source: https://github.com/nuxt-hub/core/blob/main/docs/content/docs/6.guides/3.ci-cd.md
Configure a separate job in GitHub Actions to explicitly run database migrations before deployment. This provides more control over the migration process. It requires checking out code, setting up pnpm, installing dependencies, and then running the migration command.
```yaml
jobs:
migrate:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v6
- uses: pnpm/action-setup@v6
- uses: actions/setup-node@v6
with:
node-version: 22
cache: pnpm
- run: pnpm install
- name: Run migrations
run: npx nuxt db migrate
env:
DATABASE_URL: ${{ secrets.DATABASE_URL }}
deploy:
needs: migrate
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
# ... build and deploy steps
```
--------------------------------
### Manually Configure KV Storage Driver
Source: https://github.com/nuxt-hub/core/blob/main/docs/content/docs/4.kv/1.index.md
Manually configure the `hub.kv` option with a specific unstorage driver and its options, such as the Redis driver with a URL.
```typescript
export default defineNuxtConfig({
hub: {
kv: {
driver: 'redis',
url: 'redis://localhost:6379',
/* any additional driver options */
}
}
})
```
--------------------------------
### Configure Custom Cache Driver (Redis)
Source: https://github.com/nuxt-hub/core/blob/main/docs/content/docs/5.cache/1.index.md
Configure the `cache` to use a different storage driver, such as Redis, by providing a configuration object with the driver name and connection URL.
```typescript
export default defineNuxtConfig({
hub: {
cache: {
driver: 'redis',
url: 'redis://localhost:6379'
}
}
})
```
--------------------------------
### Directory Structure for Database Files
Source: https://github.com/nuxt-hub/core/blob/main/docs/content/docs/2.database/1.index.md
Rename the database-related directories from `server/database/` to `server/db/` to align with the new structure. This includes schema and migration files.
```diff
- server/database/schema.ts
+ server/db/schema.ts
- server/database/migrations/
+ server/db/migrations/
```
--------------------------------
### Manual wrangler.jsonc Configuration for Cloudflare
Source: https://github.com/nuxt-hub/core/blob/main/docs/content/docs/1.getting-started/4.migration.md
Manually configure Cloudflare bindings for D1, R2, and KV namespaces in a `wrangler.jsonc` file for NuxtHub deployment.
```json
{
"$schema": "node_modules/wrangler/config-schema.json",
"d1_databases": [
{
"binding": "DB",
"database_name": "",
"database_id": ""
}
],
"r2_buckets": [
{
"binding": "BLOB",
"bucket_name": ""
}
],
"kv_namespaces": [
{
"binding": "KV",
"id": ""
},
{
"binding": "CACHE",
"id": ""
}
]
}
```
--------------------------------
### Configure Blob, KV, and Cache in nuxt.config.ts
Source: https://github.com/nuxt-hub/core/blob/main/docs/content/docs/1.getting-started/4.migration.md
Enable and auto-configure Blob, KV, and Cache services in `nuxt.config.ts` for multi-provider support.
```typescript
export default defineNuxtConfig({
hub: {
blob: true, // Auto-configures based on provider
kv: true, // Auto-configures based on provider
cache: true // Auto-configures based on provider
}
})
```
--------------------------------
### Configure FS Blob Driver
Source: https://github.com/nuxt-hub/core/blob/main/docs/content/docs/3.blob/1.index.md
Configure the local filesystem driver for blob storage. This is the default driver and requires specifying a directory for storing blobs.
```typescript
export default defineNuxtConfig({
hub: {
blob: {
driver: 'fs',
dir: '.data/files' // defaults to '.data/blob'
}
}
})
```
--------------------------------
### Generate Database Migrations
Source: https://github.com/nuxt-hub/core/blob/main/docs/content/docs/2.database/4.migrations.md
Command to generate new migration files based on schema changes. These files are placed in `server/db/migrations/{dialect}/`.
```bash
npx nuxt db generate
```
--------------------------------
### Build with Migrations in GitHub Actions
Source: https://github.com/nuxt-hub/core/blob/main/docs/content/docs/6.guides/3.ci-cd.md
This snippet shows how to run database migrations as part of the build process in a GitHub Actions workflow. Ensure the DATABASE_URL environment variable is set.
```yaml
- name: Build with migrations
run: pnpm build
env:
DATABASE_URL: ${{ secrets.DATABASE_URL }}
```
--------------------------------
### Neon Serverless PostgreSQL Configuration
Source: https://github.com/nuxt-hub/core/blob/main/docs/content/docs/2.database/1.index.md
Connect to Neon serverless PostgreSQL using the 'neon-http' driver, optimized for serverless environments. Requires the DATABASE_URL environment variable.
```typescript
export default defineNuxtConfig({
hub: {
db: {
dialect: 'postgresql',
driver: 'neon-http'
}
}
})
```
--------------------------------
### Import Database Client with hub:db (Legacy)
Source: https://github.com/nuxt-hub/core/blob/main/docs/content/docs/2.database/3.query.md
This virtual module is supported for backwards compatibility within Nuxt only.
```typescript
import { db, schema } from 'hub:db'
```
--------------------------------
### `nuxt db sql`
Source: https://github.com/nuxt-hub/core/blob/main/docs/content/docs/2.database/cli.md
Executes a SQL query against the database, accepting queries directly or via stdin.
```APIDOC
## `nuxt db sql`
### Description
Execute a SQL query against the database.
### Arguments
- `QUERY` (string) - The SQL query to execute. If not provided, reads from stdin.
### Options
- `--cwd` (string) - The directory to run the command in.
- `--dotenv` (string) - Point to another .env file to load, relative to the root directory.
- `-v, --verbose` (boolean) - Show verbose output.
### Example Usage
```bash
npx nuxt db sql "SELECT * FROM users"
# or
npx nuxt db sql < dump.sql
```
```
--------------------------------
### Execute SQL Query
Source: https://github.com/nuxt-hub/core/blob/main/docs/content/docs/2.database/cli.md
Executes a raw SQL query against the database. If no query is provided, it reads from standard input.
```bash
npx nuxt db sql "SELECT * FROM users"
```
```bash
npx nuxt db sql < dump.sql
```