### Server-Side DataTable Component Source: https://context7.com/makerkit/documentation/llms.txt Integrates TanStack Table with a server-side data loader for efficient tabular data display. Ensure you have '@makerkit/data-loader-supabase-nextjs' and '@kit/ui/enhanced-data-table' installed. ```tsx import { ServerDataLoader } from '@makerkit/data-loader-supabase-nextjs'; import { DataTable } from '@kit/ui/enhanced-data-table'; import { getSupabaseServerClient } from '@kit/supabase/server-client'; function TasksPage({ searchParams }) { const client = getSupabaseServerClient(); const page = searchParams.page ? parseInt(searchParams.page) : 1; return ( {({ data, page, pageSize, pageCount }) => ( )} ); } ``` -------------------------------- ### Generate documentation markdown files Source: https://github.com/makerkit/documentation/blob/main/README.md Executes the generation script for specific kits or courses. Output files are saved to the dist folder. ```bash node index.js kits/next-supabase-turbo ``` ```bash node index.js kits/remix-supabase-turbo ``` ```bash node index.js courses ``` -------------------------------- ### Interact with Supabase Clients Source: https://context7.com/makerkit/documentation/llms.txt Makerkit provides distinct clients for server-side operations with RLS and client-side real-time subscriptions. ```tsx // Server Component - uses server client with RLS import { getSupabaseServerClient } from '@kit/supabase/server-client'; export default async function TasksPage() { const supabase = getSupabaseServerClient(); const { data: tasks, error } = await supabase .from('tasks') .select('*') .order('created_at', { ascending: false }); if (error) throw new Error('Failed to load tasks'); return ; } // Client Component - uses browser client 'use client'; import { useEffect, useState } from 'react'; import { useSupabase } from '@kit/supabase/hooks/use-supabase'; export function LiveTasksList({ accountId }: { accountId: string }) { const supabase = useSupabase(); const [tasks, setTasks] = useState([]); useEffect(() => { const channel = supabase .channel('tasks-changes') .on('postgres_changes', { event: '*', schema: 'public', table: 'tasks', filter: `account_id=eq.${accountId}`, }, (payload) => { if (payload.eventType === 'INSERT') { setTasks((prev) => [...prev, payload.new as Task]); } }) .subscribe(); return () => { supabase.removeChannel(channel); }; }, [supabase, accountId]); return ; } ``` -------------------------------- ### Create Custom Welcome Email Template Source: https://context7.com/makerkit/documentation/llms.txt Build type-safe and responsive email templates using React Email. Supports internationalization and integrates with MakerKit's email components. ```typescript // Creating a custom welcome email template import { Body, Html, Preview, Tailwind, Text, render } from '@react-email/components'; import { EmailContent, CtaButton, EmailFooter, EmailHeader, EmailHeading, EmailWrapper } from '../components'; import { initializeEmailI18n } from '../lib/i18n'; interface Props { userName: string; productName: string; dashboardUrl: string; language?: string; } export async function renderWelcomeEmail(props: Props) { const { t } = await initializeEmailI18n({ language: props.language, namespace: 'welcome-email', }); const html = await render( {t('welcome-email:previewText', { productName: props.productName })} {t('welcome-email:heading')} {t('welcome-email:hello', { userName: props.userName })} {t('welcome-email:ctaButton')} {props.productName} , ); return { html, subject: t('welcome-email:subject') }; } ``` ```typescript // Sending the email import { getMailer } from '@kit/mailers'; import { renderWelcomeEmail } from '@kit/email-templates'; async function sendWelcome(user: { email: string; name: string }) { const { html, subject } = await renderWelcomeEmail({ userName: user.name, productName: 'Your App', dashboardUrl: 'https://app.example.com/dashboard', }); const mailer = await getMailer(); await mailer.sendEmail({ to: user.email, from: process.env.EMAIL_SENDER!, subject, html, }); } ``` -------------------------------- ### Create Task Server Action with enhanceAction Source: https://context7.com/makerkit/documentation/llms.txt Wraps a Server Action with authentication and Zod validation for creating tasks. Requires authentication and revalidates the '/tasks' path on success. ```tsx 'use server'; import { z } from 'zod'; import { revalidatePath } from 'next/cache'; import { enhanceAction } from '@kit/next/actions'; import { getSupabaseServerClient } from '@kit/supabase/server-client'; const CreateTaskSchema = z.object({ title: z.string().min(1, 'Title is required').max(200), description: z.string().optional(), accountId: z.string().uuid(), }); export const createTask = enhanceAction( async (data, user) => { const supabase = getSupabaseServerClient(); const { error } = await supabase.from('tasks').insert({ title: data.title, description: data.description, account_id: data.accountId, created_by: user.id, }); if (error) { return { success: false, error: 'Failed to create task' }; } revalidatePath('/tasks'); return { success: true }; }, { schema: CreateTaskSchema, auth: true, // Requires authentication (default) } ); ``` -------------------------------- ### Configure Billing Schema Source: https://context7.com/makerkit/documentation/llms.txt Define products, pricing, and plans for various payment providers. This configuration drives UI elements and checkout processes. ```typescript // apps/web/config/billing.config.ts import { createBillingSchema } from '@kit/billing'; const provider = process.env.NEXT_PUBLIC_BILLING_PROVIDER ?? 'stripe'; export default createBillingSchema({ provider, products: [ { id: 'pro', name: 'Pro', description: 'For professionals and small teams', currency: 'USD', badge: 'Popular', highlighted: true, features: ['Unlimited projects', 'Priority support', 'Advanced analytics'], plans: [ { id: 'pro-monthly', name: 'Pro Monthly', paymentType: 'recurring', interval: 'month', trialDays: 14, lineItems: [ { id: 'price_pro_monthly', // Stripe Price ID name: 'Pro Plan', cost: 29, type: 'flat', }, ], }, { id: 'pro-yearly', name: 'Pro Yearly', paymentType: 'recurring', interval: 'year', lineItems: [ { id: 'price_pro_yearly', name: 'Pro Plan', cost: 290, type: 'flat', }, ], }, ], }, { id: 'team', name: 'Team', description: 'Per-seat pricing for teams', currency: 'USD', plans: [ { id: 'team-monthly', name: 'Team Monthly', paymentType: 'recurring', interval: 'month', lineItems: [ { id: 'price_team_seats', name: 'Team Seats', cost: 0, type: 'per_seat', tiers: [ { upTo: 5, cost: 0 }, // First 5 free { upTo: 'unlimited', cost: 15 }, ], }, ], }, ], }, ], }); ``` -------------------------------- ### Supabase Clients Source: https://context7.com/makerkit/documentation/llms.txt MakerKit provides three Supabase clients for different environments: `useSupabase()` for Client Components, `getSupabaseServerClient()` for Server Components and Server Actions, and `getSupabaseServerAdminClient()` for admin operations that bypass Row Level Security. ```APIDOC ## Supabase Clients ### Description Provides Supabase client instances for various environments: Client Components, Server Components/Actions, and Admin operations. ### Client Types 1. **`useSupabase()`**: For Client Components. Uses the browser Supabase client. 2. **`getSupabaseServerClient()`**: For Server Components and Server Actions. Uses the server-side Supabase client with Row Level Security (RLS) enabled. 3. **`getSupabaseServerAdminClient()`**: For admin operations. Uses the server-side Supabase client bypassing Row Level Security (RLS). ### Usage Examples #### Server Component Example ```tsx // Server Component - uses server client with RLS import { getSupabaseServerClient } from '@kit/supabase/server-client'; export default async function TasksPage() { const supabase = getSupabaseServerClient(); const { data: tasks, error } = await supabase .from('tasks') .select('*') .order('created_at', { ascending: false }); if (error) throw new Error('Failed to load tasks'); return ; } ``` #### Client Component Example (with Realtime Subscription) ```tsx 'use client'; import { useEffect, useState } from 'react'; import { useSupabase } from '@kit/supabase/hooks/use-supabase'; export function LiveTasksList({ accountId }: { accountId: string }) { const supabase = useSupabase(); const [tasks, setTasks] = useState([]); useEffect(() => { const channel = supabase .channel('tasks-changes') .on('postgres_changes', { event: '*', schema: 'public', table: 'tasks', filter: `account_id=eq.${accountId}`, }, (payload) => { if (payload.eventType === 'INSERT') { setTasks((prev) => [...prev, payload.new as Task]); } }) .subscribe(); return () => { supabase.removeChannel(channel); }; }, [supabase, accountId]); return
    {tasks.map((task) =>
  • {task.title}
  • )}
; } ``` ### Parameters None for the client retrieval functions themselves, but subsequent Supabase client methods will follow Supabase JS SDK conventions. ### Request Example See Usage Examples above. ### Response - **supabaseClient** (object) - An instance of the Supabase client configured for the specific environment (client, server, or admin). ``` -------------------------------- ### MakerKit Environment Variables Source: https://context7.com/makerkit/documentation/llms.txt Lists essential environment variables for configuring Supabase, app identity, billing, email, and feature flags in a MakerKit project. These should be set in .env files. ```bash # Required - Supabase Configuration NEXT_PUBLIC_SUPABASE_URL=https://yourproject.supabase.co NEXT_PUBLIC_SUPABASE_PUBLIC_KEY=your-public-key SUPABASE_SECRET_KEY=your-service-role-key # Required - App Identity NEXT_PUBLIC_SITE_URL=https://yourapp.com NEXT_PUBLIC_PRODUCT_NAME=Your Product NEXT_PUBLIC_SITE_TITLE="Your Product - Tagline" NEXT_PUBLIC_SITE_DESCRIPTION="Your product description" # Billing (Stripe) NEXT_PUBLIC_BILLING_PROVIDER=stripe NEXT_PUBLIC_STRIPE_PUBLISHABLE_KEY=pk_test_... STRIPE_SECRET_KEY=sk_test_... STRIPE_WEBHOOK_SECRET=whsec_... # Email MAILER_PROVIDER=resend RESEND_API_KEY=re_... EMAIL_SENDER="Your App " # Feature Flags NEXT_PUBLIC_ENABLE_TEAM_ACCOUNTS=true NEXT_PUBLIC_ENABLE_TEAM_ACCOUNTS_BILLING=true NEXT_PUBLIC_ENABLE_NOTIFICATIONS=true ``` -------------------------------- ### Generate Markdown Documentation Files Source: https://context7.com/makerkit/documentation/llms.txt This script recursively finds .mdoc files in a directory and concatenates them. It requires a source path argument and an optional word limit per file. ```javascript // Generate markdown files for a specific kit // Run: node index.js kits/next-supabase-turbo import fs from 'fs/promises'; import path from 'path'; const DIST_FOLDER = 'dist'; const WORDS_PER_FILE = 5000; async function findMarkdocFiles(dir) { const files = await fs.readdir(dir, { withFileTypes: true }); let markdocFiles = []; for (const file of files) { const fullPath = path.join(dir, file.name); if (file.isDirectory()) { markdocFiles = markdocFiles.concat(await findMarkdocFiles(fullPath)); } else if (path.extname(file.name) === '.mdoc') { markdocFiles.push(fullPath); } } return markdocFiles; } async function main() { const sourcePath = process.argv[2]; const wordsPerFile = parseInt(process.argv[3]) || WORDS_PER_FILE; const files = await findMarkdocFiles(sourcePath); await concatenateFiles(files, wordsPerFile); console.log('Files saved to dist/ folder'); } ``` -------------------------------- ### Create and Secure Notes Table Source: https://context7.com/makerkit/documentation/llms.txt Defines a 'notes' table with audit fields, enables Row Level Security (RLS), and grants permissions. Use this to add custom data structures with fine-grained access control. ```sql -- Create the main table with audit fields CREATE TABLE IF NOT EXISTS public.notes ( id uuid PRIMARY KEY DEFAULT gen_random_uuid(), account_id uuid NOT NULL REFERENCES public.accounts(id) ON DELETE CASCADE, title varchar(500) NOT NULL, content text, is_published boolean NOT NULL DEFAULT false, tags text[] DEFAULT '{}', created_at timestamptz NOT NULL DEFAULT now(), updated_at timestamptz NOT NULL DEFAULT now(), created_by uuid REFERENCES auth.users(id), updated_by uuid REFERENCES auth.users(id) ); -- Enable RLS (NEVER skip this!) ALTER TABLE public.notes ENABLE ROW LEVEL SECURITY; -- Grant permissions REVOKE ALL ON public.notes FROM authenticated, service_role; GRANT SELECT, INSERT, UPDATE, DELETE ON public.notes TO authenticated, service_role; -- SELECT policy: Read published notes or own drafts CREATE POLICY "notes_select" ON public.notes FOR SELECT TO authenticated USING ( account_id = (SELECT auth.uid()) OR (public.has_role_on_account(account_id) AND is_published = true) OR (public.has_role_on_account(account_id) AND created_by = auth.uid()) OR public.has_permission(auth.uid(), account_id, 'notes.manage') ); -- INSERT policy: Must have create permission CREATE POLICY "notes_insert" ON public.notes FOR INSERT TO authenticated WITH CHECK ( account_id = (SELECT auth.uid()) OR public.has_permission(auth.uid(), account_id, 'notes.create') ); -- Automatic timestamp triggers CREATE TRIGGER notes_updated_at BEFORE UPDATE ON public.notes FOR EACH ROW EXECUTE FUNCTION kit.trigger_set_timestamps(); ``` -------------------------------- ### Configure word count for generated files Source: https://github.com/makerkit/documentation/blob/main/README.md Sets the maximum number of words per generated markdown file using a second argument. ```bash node index.js kits 4000 ``` -------------------------------- ### Authentication API - requireUser Source: https://context7.com/makerkit/documentation/llms.txt The `requireUser` function checks authentication status in Server Components, Server Actions, and Route Handlers. It handles both standard auth and MFA verification in a single call, returning user data or redirect information for unauthenticated users. ```APIDOC ## Authentication API - requireUser ### Description Checks authentication status in Server Components, Server Actions, and Route Handlers. Handles standard auth and MFA verification, returning user data or redirect information. ### Method N/A (Function usage) ### Endpoint N/A (Function usage) ### Parameters #### Path Parameters None #### Query Parameters None #### Request Body None ### Request Example ```tsx import { redirect } from 'next/navigation'; import { requireUser } from '@kit/supabase/require-user'; import { getSupabaseServerClient } from '@kit/supabase/server-client'; export default async function DashboardPage() { const client = getSupabaseServerClient(); const auth = await requireUser(client); if (auth.error) { redirect(auth.redirectTo); } return (

Dashboard

Logged in as: {auth.data.email}

MFA status: {auth.data.aal === 'aal2' ? 'Verified' : 'Not verified'}

); } ``` ### Response #### Success Response (200) - **data** (object) - User authentication data including email and MFA status. - **error** (null) - Indicates no error occurred. #### Error Response - **data** (null) - No user data. - **error** (object) - Error object. - **redirectTo** (string) - URL to redirect to for authentication. #### Response Example ```json { "data": { "email": "user@example.com", "aal": "aal2" }, "error": null, "redirectTo": null } ``` ```json { "data": null, "error": { "message": "User not authenticated" }, "redirectTo": "/sign-in" } ``` ``` -------------------------------- ### Authenticate Server Components with requireUser Source: https://context7.com/makerkit/documentation/llms.txt Use requireUser to verify authentication and MFA status in Server Components, Server Actions, or Route Handlers. It returns user data or handles redirection for unauthenticated requests. ```tsx import { redirect } from 'next/navigation'; import { requireUser } from '@kit/supabase/require-user'; import { getSupabaseServerClient } from '@kit/supabase/server-client'; export default async function DashboardPage() { const client = getSupabaseServerClient(); const auth = await requireUser(client); if (auth.error) { redirect(auth.redirectTo); } return (

Dashboard

Logged in as: {auth.data.email}

MFA status: {auth.data.aal === 'aal2' ? 'Verified' : 'Not verified'}

); } ``` -------------------------------- ### Authentication API - useUser Hook Source: https://context7.com/makerkit/documentation/llms.txt The `useUser` hook provides reactive access to user data in client components. It reads from the auth context and updates automatically on auth state changes, returning the Supabase User object or null. ```APIDOC ## Authentication API - useUser Hook ### Description Provides reactive access to user data in client components. Reads from the auth context and updates automatically on auth state changes. ### Method N/A (Hook usage) ### Endpoint N/A (Hook usage) ### Parameters None ### Request Example ```tsx 'use client'; import { useUser } from '@kit/supabase/hooks/use-user'; function UserMenu() { const user = useUser(); if (!user) { return
Loading...
; } return (
{user.email} Avatar
); } ``` ### Response - **user** (object | null) - The Supabase User object if authenticated, otherwise null. ### Response Example ```json { "id": "123e4567-e89b-12d3-a456-426614174000", "email": "user@example.com", "user_metadata": { "avatar_url": "https://example.com/avatar.jpg" }, "created_at": "2023-01-01T12:00:00Z", "role": "user" } ``` ```json null ``` ``` -------------------------------- ### Update Team Settings Server Action with enhanceAction Source: https://context7.com/makerkit/documentation/llms.txt A permission-gated Server Action for updating team settings. It uses `enhanceAction` to check if the authenticated user has the 'settings.manage' permission for the specified account. ```tsx // Permission-gated Server Action export const updateTeamSettings = enhanceAction( async (data, user) => { const client = getSupabaseServerClient(); const api = createTeamAccountsApi(client); const canManage = await api.hasPermission({ accountId: data.accountId, userId: user.id, permission: 'settings.manage', }); if (!canManage) { return { success: false, error: 'Permission denied' }; } // Update team settings... return { success: true }; }, { schema: UpdateTeamSchema } ); ``` -------------------------------- ### Check Account Plan Access Source: https://context7.com/makerkit/documentation/llms.txt Fetches subscription data for a given account ID to determine if the user has access to a required plan. Handles cases with no subscription or inactive subscriptions. ```tsx import { createAccountsApi } from '@kit/accounts/api'; import { getSupabaseServerClient } from '@kit/supabase/server-client'; async function checkPlanAccess(accountId: string, requiredPlan: string) { const client = getSupabaseServerClient(); const api = createAccountsApi(client); const subscription = await api.getSubscription(accountId); if (!subscription) { return { hasAccess: false, reason: 'no_subscription' }; } if (subscription.status !== 'active' && subscription.status !== 'trialing') { return { hasAccess: false, reason: 'inactive_subscription' }; } const hasRequiredPlan = subscription.items.some( (item) => item.product_id === requiredPlan ); return hasRequiredPlan ? { hasAccess: true } : { hasAccess: false, reason: 'wrong_plan' }; } ``` -------------------------------- ### Public Contact Form Server Action with enhanceAction Source: https://context7.com/makerkit/documentation/llms.txt A public Server Action for submitting a contact form, including bot protection via captcha. Authentication is disabled for this action. ```tsx // Public action without authentication export const submitContactForm = enhanceAction( async (data) => { await sendEmail(data); return { success: true }; }, { schema: ContactFormSchema, auth: false, captcha: true, // Bot protection for public forms } ); ``` -------------------------------- ### Account Switcher Component Source: https://context7.com/makerkit/documentation/llms.txt A React component that loads and displays a list of user accounts, allowing the user to switch between them. It uses the Account API to fetch account data. ```tsx // Account switcher component async function AccountSwitcher() { const client = getSupabaseServerClient(); const api = createAccountsApi(client); const accounts = await api.loadUserAccounts(); return ( ); } ``` -------------------------------- ### Team Account Settings Page Source: https://context7.com/makerkit/documentation/llms.txt A page component that displays different sections (Settings, Billing, Invite Member) based on the user's permissions within a team account. It fetches workspace details and checks permissions. ```tsx import { createTeamAccountsApi } from '@kit/team-accounts/api'; import { getSupabaseServerClient } from '@kit/supabase/server-client'; async function TeamSettingsPage({ params }: { params: { account: string } }) { const client = getSupabaseServerClient(); const api = createTeamAccountsApi(client); const workspace = await api.getAccountWorkspace(params.account); const permissions = { canManageSettings: workspace.account.permissions.includes('settings.manage'), canManageBilling: workspace.account.permissions.includes('billing.manage'), canInviteMembers: workspace.account.permissions.includes('members.invite'), }; return (
{permissions.canManageSettings && } {permissions.canManageBilling && } {permissions.canInviteMembers && }
); } ``` -------------------------------- ### Access User Data with useUser Hook Source: https://context7.com/makerkit/documentation/llms.txt The useUser hook provides reactive access to the current user object in client-side components. It automatically updates when the authentication state changes. ```tsx 'use client'; import { useUser } from '@kit/supabase/hooks/use-user'; function UserMenu() { const user = useUser(); if (!user) { return
Loading...
; } return (
{user.email} Avatar
); } ``` === COMPLETE CONTENT === This response contains all available snippets from this library. No additional content exists. Do not make further requests.