Beginner

Next.js

A Next.js 14 App Router project with tacobase auth and CRUD. Includes a public home page with a drop-in auth form and a protected /dashboard route that redirects unauthenticated users.

Next.js 14App RouterReactTypeScriptCRUDAuth

What's in this example

Zero-config client

createClient() reads NEXT_PUBLIC_ env vars automatically.

Protected dashboard

Redirect to / if user is not authenticated.

useCollection hook

Filtered and sorted list tied to the current user.

CRUD

Create and delete posts directly from the dashboard.

Next.js env prefix

Client-side env vars must be prefixed with NEXT_PUBLIC_. Use .env.local so they are not committed to git.

Setup

cp .env.example .env.local
# NEXT_PUBLIC_TACOBASE_URL=https://your-app.tacobase.dev
# NEXT_PUBLIC_TACOBASE_API_KEY=tbk_...

npm install
npm run dev

Key files

src/lib/tacobase.ts

// src/lib/tacobase.ts
import { createClient } from '@tacobase/client'

// Zero-config: reads NEXT_PUBLIC_TACOBASE_URL and
// NEXT_PUBLIC_TACOBASE_API_KEY from env automatically
const db = createClient()

export default db

src/app/page.tsx

// src/app/page.tsx  — public home page
'use client'

import { useAuth, AuthForm } from '@tacobase/react'
import { useRouter } from 'next/navigation'

export default function HomePage() {
  const { user, loading } = useAuth()
  const router = useRouter()

  if (loading) return <p>Loading...</p>
  if (user) {
    router.push('/dashboard')
    return null
  }

  return (
    <AuthForm
      providers={['google', 'github']}
      onSuccess={() => router.push('/dashboard')}
    />
  )
}

src/app/dashboard/page.tsx

// src/app/dashboard/page.tsx  — protected route
'use client'

import { useAuth, useCollection } from '@tacobase/react'
import db from '@/lib/tacobase'

export default function DashboardPage() {
  const { user, loading, signOut } = useAuth()
  const { data: posts } = useCollection('posts', {
    filter: `author = "${user?.id}"`,
    sort: '-created',
  })

  if (loading) return <p>Loading...</p>
  if (!user) { router.push('/'); return null }

  async function createPost(title: string) {
    await db.collection('posts').create({ title, author: user!.id })
  }

  // ...
}