### Run Development Server for App Source: https://www.mf2.dev/docs/apps/app Use this command to start the development server specifically for the 'app' package. Ensure Turbo is installed and configured. ```bash turbo dev --filter=app ``` -------------------------------- ### Install a Skill using CLI Source: https://www.mf2.dev/docs/skills Use this command to install any available skill from a GitHub repository. Replace placeholders with the owner/repo and desired skill name. ```bash bunx skills add --skill ``` -------------------------------- ### Start Convex Backend Separately Source: https://www.mf2.dev/docs/commands This command starts the Convex backend service independently for development. ```bash bunx convex dev ``` -------------------------------- ### Verify Tool Installations Source: https://www.mf2.dev/docs/setup/prerequisites Check if Bun, Node.js, Stripe CLI, and Mintlify CLI are installed correctly by verifying their versions. Run this command after installing the required tools. ```bash bun --version node --version git --version stripe --version mint --version ``` -------------------------------- ### Install Convex Best Practices Skill Source: https://www.mf2.dev/docs/skills Installs the Convex best practices skill for mf². Recommended for production Convex patterns, validation, and error handling. ```bash bunx skills add waynesutton/convexskills --skill convex-best-practices ``` -------------------------------- ### Scaffold a New mf² Project Source: https://www.mf2.dev/docs/setup/installation Use this command to create a new mf² application. Ensure you have Bun installed. Navigate into the created directory and install dependencies. ```bash bunx create-mf2-app my-app cd my-app bun install ``` -------------------------------- ### Install Next.js Best Practices Skill Source: https://www.mf2.dev/docs/skills Installs the Next.js best practices skill for mf². Covers 23+ topics including RSC boundaries, async patterns, and metadata. ```bash bunx skills add vercel-labs/next-skills --skill next-best-practices ``` -------------------------------- ### Install Convex Skill Source: https://www.mf2.dev/docs/skills Installs the Convex skill for mf². Recommended for Convex functions, schema, real-time patterns, and security. ```bash bunx skills add waynesutton/convexskills --skill convex ``` -------------------------------- ### Install AI SDK Skill Source: https://www.mf2.dev/docs/skills Installs the Vercel AI SDK skill for mf². Supports streaming, tools, agents, and provider integration. ```bash bunx skills add vercel/ai --skill ai-sdk ``` -------------------------------- ### Start All Apps in Development Mode Source: https://www.mf2.dev/docs/commands Use this command to start all applications within the monorepo in development mode simultaneously. ```bash bun run dev ``` -------------------------------- ### Run Documentation Development Server with Mint CLI Source: https://www.mf2.dev/docs/apps/docs Use this command to start the development server for the documentation site directly with the Mint CLI. Specify the port if needed. ```bash mint dev --port 3004 ``` -------------------------------- ### Run Storybook Development Server Source: https://www.mf2.dev/docs/apps/storybook Use this command to start the Storybook development server. The preview will be available at localhost:6006. ```bash turbo dev --filter=storybook ``` -------------------------------- ### Run Documentation Development Server with Turbo Source: https://www.mf2.dev/docs/apps/docs Use this command to start the development server for the documentation site using Turbo. Ensure the 'docs' filter is applied. ```bash turbo dev --filter=docs ``` -------------------------------- ### Install Frontend Design Skill Source: https://www.mf2.dev/docs/skills Installs the frontend design skill for mf². Focuses on distinctive UI direction, including typography, color, motion, and layout. ```bash bunx skills add anthropics/skills --skill frontend-design ``` -------------------------------- ### Run API Development Server Source: https://www.mf2.dev/docs/apps/api Use this command to start the development server for the API project. It filters the build to only include the 'api' package. ```bash turbo dev --filter=api ``` -------------------------------- ### Run Email Dev Server Source: https://www.mf2.dev/docs/apps/email Start the development server for the email package using Turbo. Ensure the email filter is applied. ```bash turbo dev --filter=email ``` -------------------------------- ### Install Convex Rate Limiter Component Source: https://www.mf2.dev/docs/packages/rate-limit Installs the Convex Rate Limiter component using Bun. This is the first step to integrating rate limiting within Convex functions. ```bash bun add @convex-dev/rate-limiter ``` -------------------------------- ### Run Mobile App Directly with Expo Source: https://www.mf2.dev/docs/apps/mobile Navigate to the mobile app directory and start the Expo development server directly. This is an alternative to using Turbo for starting the app. ```bash cd apps/mobile && bunx expo start ``` -------------------------------- ### Run Mobile App with Turbo Source: https://www.mf2.dev/docs/apps/mobile Use this command to start the mobile application development server via Turbo. Ensure your environment is set up for Turbo builds. ```bash turbo dev:mobile ``` -------------------------------- ### Install Tailwind Design System Skill Source: https://www.mf2.dev/docs/skills Installs the Tailwind CSS v4 design system skill for mf². Includes support for tokens, variants, and OKLCH colors. ```bash bunx skills add wshobson/agents --skill tailwind-design-system ``` -------------------------------- ### Run Development Server with Turbo Source: https://www.mf2.dev/docs/apps/web Use this command to start the development server for the web application using Turbo. The `--filter=web` flag ensures only the web package is built and run. ```bash turbo dev --filter=web ``` -------------------------------- ### Add New Environment Variables Source: https://www.mf2.dev/docs/setup/env Example of adding a new server and client environment variable to the schema. Remember to also update your .env and .env.example files. ```typescript import { createEnv } from '@t3-oss/env-nextjs'; import { z } from 'zod'; export const env = createEnv({ server: { MY_NEW_SECRET: z.string().min(1), }, client: { NEXT_PUBLIC_MY_VALUE: z.string().optional(), }, runtimeEnv: { MY_NEW_SECRET: process.env.MY_NEW_SECRET, NEXT_PUBLIC_MY_VALUE: process.env.NEXT_PUBLIC_MY_VALUE, }, }); ``` -------------------------------- ### Start a Specific App Source: https://www.mf2.dev/docs/setup/installation To run only a single application, use the `--filter` flag with the `bun run dev` command. Replace `app` with the desired application name (e.g., `web`, `api`, `docs`). ```bash bun run dev --filter=app ``` -------------------------------- ### Example Imports from Packages Source: https://www.mf2.dev/docs/structure Demonstrates how to import modules from different packages within the monorepo, including UI components and utility functions. Note the different import paths for web and mobile equivalents. ```typescript import { auth } from "@repo/auth"; import { Button } from "@repo/design-system/components/ui/button"; import { analytics } from "@repo/analytics"; // Mobile equivalents import { Button } from "@repo/design-system-native/components/ui/button"; ``` -------------------------------- ### Create a Chat Agent with Tools Source: https://www.mf2.dev/docs/packages/ai Define a chat agent with custom tools for specific functionalities. This example shows how to create an agent that can access weather information. ```typescript import { createChatAgent, tool, z } from "@repo/ai/agent"; const agent = createChatAgent(token, { weather: tool({ description: "Get the weather for a location", parameters: z.object({ city: z.string() }), execute: async ({ city }) => `72°F in ${city}`, }), }); ``` -------------------------------- ### Colocating Non-Component Files Source: https://www.mf2.dev/docs/colocation Example of colocating route-specific files like schemas, types, and hooks within the same route folder for better organization. ```tree apps/app/src/app/settings/ ├── page.tsx ├── _components/ │ └── settings-form.tsx ├── _lib/ │ └── schema.ts # Zod schema for settings form └── _hooks/ └── use-settings.ts # Hook for settings state ``` -------------------------------- ### Create a New MDX Documentation Page Source: https://www.mf2.dev/docs/apps/docs Example of a basic MDX file structure for a new documentation page. The file name determines the URL slug, and metadata like title and description are defined in the frontmatter. ```mdx --- title: 'Hello World' description: 'A new documentation page.' --- ``` -------------------------------- ### Create a Retrieval-Augmented Generation Pipeline Source: https://www.mf2.dev/docs/packages/ai Build RAG pipelines by defining stages for query preprocessing, retrieval, and reranking. This example creates a pipeline with 'rewrite' and 'stepback' stages. ```typescript import { createPipeline } from "@repo/ai/rag"; const pipeline = createPipeline({ stages: ["rewrite", "stepback"], retriever: myRetriever, }); const results = await pipeline.run("How does auth work?"); ``` -------------------------------- ### Authenticate Stripe CLI Source: https://www.mf2.dev/docs/setup/prerequisites Log in to your Stripe account using the Stripe CLI. This is required after installing the Stripe CLI. ```bash stripe login ``` -------------------------------- ### Import and Use Design System Components Source: https://www.mf2.dev/docs/packages/design-system Import and use various UI components like Button, Card, and Input from the design system package. This example demonstrates a settings form. ```tsx import { Button } from "@repo/design-system/components/ui/button"; import { Card, CardContent, CardHeader, CardTitle } from "@repo/design-system/components/ui/card"; import { Input } from "@repo/design-system/components/ui/input"; export function SettingsForm() { return ( Settings ); } ``` -------------------------------- ### Configure Upstash Rate Limiter with Different Window Source: https://www.mf2.dev/docs/packages/rate-limit Demonstrates configuring the Upstash rate limiter with a different sliding window policy. This example uses a limit of 5 requests per 15 minutes for authentication endpoints. ```typescript const authLimiter = createRateLimiter({ limiter: slidingWindow(5, "15 m"), prefix: "auth", }); ``` -------------------------------- ### Update All npm Dependencies Source: https://www.mf2.dev/docs/commands Updates all npm dependencies across all `package.json` files to their latest versions and installs them. It's recommended to run `bun run build` and `bun run dev` afterward. ```bash bun run bump-deps ``` -------------------------------- ### Register Pre-installed Convex Components Source: https://www.mf2.dev/docs/components Register pre-installed components like Stripe, Resend, Workflow, Action Retrier, and Migrations in your `convex.config.ts` file. Ensure all necessary packages are installed. ```typescript import { defineApp } from "convex/server"; import actionRetrier from "@convex-dev/action-retrier/convex.config.js"; import migrations from "@convex-dev/migrations/convex.config.js"; import resend from "@convex-dev/resend/convex.config.js"; import stripe from "@convex-dev/stripe/convex.config.js"; import workflow from "@convex-dev/workflow/convex.config.js"; const app = defineApp(); app.use(actionRetrier); app.use(migrations); app.use(resend); app.use(stripe); app.use(workflow); export default app; ``` -------------------------------- ### Use Shared System Prompts Source: https://www.mf2.dev/docs/packages/ai Import and utilize shared system prompts for common chat functionalities like generating titles. This example shows how to generate a chat title. ```typescript import { SYSTEM_PROMPT } from "@repo/ai/prompts"; import { generateChatTitle } from "@repo/ai/prompts/title"; const title = await generateChatTitle("How do I deploy to Vercel?"); ``` -------------------------------- ### Fetch and Display Blog Post with CMS Source: https://www.mf2.dev/docs/packages/cms Use `fetchBlogPost` to retrieve a blog post by its slug and display its title, publication date, and content. Ensure the CMS package is installed and configured. ```tsx import { fetchBlogPost } from "@repo/cms"; export default async function BlogPost({ params }: { params: { slug: string } }) { const post = await fetchBlogPost(params.slug); return (

{post.title}

{post.content}
); } ``` -------------------------------- ### Send Transactional Email Source: https://www.mf2.dev/docs/apps/email Send a transactional email using the `@repo/email` package. This example shows how to import the `sendEmail` function and a React Email template, then use them to send a welcome email. ```typescript import { sendEmail } from "@repo/email"; import Welcome from "@repo/email/templates/welcome"; await sendEmail({ to: "user@example.com", subject: "Welcome aboard", react: Welcome({ name: "Jane" }), }); ``` -------------------------------- ### Configure Stripe Payment Keys Source: https://www.mf2.dev/docs/setup/env Set these environment variables for Stripe integration. Obtain your keys from the Stripe Dashboard. The webhook secret is generated when starting the Stripe CLI for local testing. ```bash STRIPE_SECRET_KEY="sk_test..." STRIPE_WEBHOOK_SECRET="whsec_..." ``` -------------------------------- ### Use Convex Rate Limiter in Mutations Source: https://www.mf2.dev/docs/packages/rate-limit Applies rate limiting to a Convex mutation using the defined rate limiter. This example uses the 'throws: true' option to automatically throw a ConvexError when the limit is exceeded. ```typescript import { rateLimiter } from "../rateLimits"; export const send = mutation({ args: { body: v.string() }, handler: async (ctx, args) => { const user = await getCurrentUserOrThrow(ctx); await rateLimiter.limit(ctx, "sendMessage", { key: user._id, throws: true, }); // Handle message }, }); ``` -------------------------------- ### Route AI Requests with Gateway Source: https://www.mf2.dev/docs/packages/ai Utilize the AI Gateway to route requests to specific AI models from different providers. This example demonstrates generating text using the Claude Sonnet model via the gateway. ```typescript import { gateway } from "@repo/ai/gateway"; import { generateText } from "ai"; const { text } = await generateText({ model: gateway("anthropic/claude-sonnet-4.6"), prompt: "Explain monorepos in one sentence.", }); ``` -------------------------------- ### Initialize Environment Variables Source: https://www.mf2.dev/docs/commands Creates local and production environment files (`.env.local`, `.env.production`) from a template (`.env.example`). ```bash bun run env:init ``` -------------------------------- ### Initialize, Check, and Push Environment Variables Source: https://www.mf2.dev/docs/setup/env These Bun scripts manage environment files. `env:init` creates `.env.local` and `.env.production` from `.env.example`. `env:check` validates that all required keys are present. `env:push` syncs variables to Vercel and Convex. ```bash bun run env:init bun run env:check bun run env:push ``` -------------------------------- ### Create mf² App Source: https://www.mf2.dev/docs Use this command to bootstrap a new mf² application. This command initializes the monorepo structure and sets up the necessary configurations. ```bash bunx create-mf2-app ``` -------------------------------- ### Deploy Convex to Production Source: https://www.mf2.dev/docs/commands Deploys the Convex backend service to the production environment. ```bash bunx convex deploy ``` -------------------------------- ### Get Webhook Portal URL Source: https://www.mf2.dev/docs/packages/webhooks Retrieve the URL for the webhook management portal, allowing customers to manage their webhook endpoints. ```APIDOC ## getPortalUrl ### Description Generates a URL for the self-service webhook management portal. ### Method Signature `getPortalUrl({ appId: string })` ### Parameters #### Arguments - **appId** (string) - Required - The identifier for the application. ### Response #### Success Response (200) - **url** (string) - The URL for the webhook portal. ### Request Example ```ts const portalUrl = await getPortalUrl({ appId: userId }); return Response.json({ url: portalUrl }); ``` ``` -------------------------------- ### Get Webhook Portal URL Source: https://www.mf2.dev/docs/packages/webhooks Retrieve the URL for the webhook management portal. This is useful for providing customers with a self-service interface to manage their webhook endpoints. ```typescript import { getPortalUrl } from "@repo/webhooks"; const portalUrl = await getPortalUrl({ appId: userId }); return Response.json({ url: portalUrl }); ``` -------------------------------- ### Get Feature Flag (Server-Side) Source: https://www.mf2.dev/docs/packages/feature-flags Use `getFlag` to retrieve the boolean value of a feature flag on the server. Ensure the feature flag is defined in your project. ```tsx import { getFlag } from "@repo/feature-flags"; const showNewEditor = await getFlag("new-editor"); ``` -------------------------------- ### Get Current User in Convex Backend Functions Source: https://www.mf2.dev/docs/packages/convex Use the `getCurrentUserOrThrow` helper to access the current user's identity in your Convex backend functions. ```ts import { getCurrentUserOrThrow } from "../auth/users"; export const send = mutation({ args: { body: v.string() }, handler: async (ctx, args) => { const user = await getCurrentUserOrThrow(ctx); await ctx.db.insert("messages", { body: args.body, userId: user._id }); }, }); ``` -------------------------------- ### Define Feature Flags Source: https://www.mf2.dev/docs/packages/feature-flags Use `defineFlags` to declare your feature flags, including their default values and targeting rules. This setup is typically done once in your application. ```ts import { defineFlags } from "@repo/feature-flags"; export const flags = defineFlags({ "new-editor": { defaultValue: false, description: "Enable the new rich text editor", }, "beta-features": { defaultValue: false, targeting: { percentage: 10 }, }, }); ``` -------------------------------- ### Configure AI (Vercel AI Gateway) Source: https://www.mf2.dev/docs/setup/env Set AI_GATEWAY_API_KEY and AI_GATEWAY_URL for Vercel AI Gateway. ```bash AI_GATEWAY_API_KEY="..." AI_GATEWAY_URL="..." ``` -------------------------------- ### Configure Observability (BetterStack) Source: https://www.mf2.dev/docs/setup/env Set BETTERSTACK_API_KEY and BETTERSTACK_URL for BetterStack observability. ```bash BETTERSTACK_API_KEY="..." BETTERSTACK_URL="..." ``` -------------------------------- ### Configure Analytics (PostHog) Source: https://www.mf2.dev/docs/setup/env Set NEXT_PUBLIC_POSTHOG_KEY and NEXT_PUBLIC_POSTHOG_HOST for PostHog analytics integration. ```bash NEXT_PUBLIC_POSTHOG_KEY="phc_..." NEXT_PUBLIC_POSTHOG_HOST="https://app.posthog.com" ``` -------------------------------- ### Add a Button Story to Storybook Source: https://www.mf2.dev/docs/apps/storybook Create a `.stories.tsx` file in `apps/storybook/stories` to define stories for a component. This example shows how to add a default story for the Button component. ```tsx import type { Meta, StoryObj } from "@storybook/react"; import { Button } from "@repo/design-system/components/ui/button"; const meta: Meta = { title: "Components/Button", component: Button, }; export default meta; export const Default: StoryObj = { args: { children: "Click me", variant: "default" }, }; ``` -------------------------------- ### Get Feature Flag (Client-Side) Source: https://www.mf2.dev/docs/packages/feature-flags Use the `useFlag` hook to access feature flag values within client components. This hook is designed for React client-side rendering. ```tsx "use client"; import { useFlag } from "@repo/feature-flags"; const showBeta = useFlag("beta-features"); ``` -------------------------------- ### Build All Apps Source: https://www.mf2.dev/docs/commands Builds all applications in the monorepo. This command also runs tests before initiating the build process. ```bash bun run build ``` -------------------------------- ### Configure Clerk Authentication Source: https://www.mf2.dev/docs/setup/env Set these environment variables to enable Clerk authentication. Obtain your keys from the Clerk Dashboard. ```bash NEXT_PUBLIC_CLERK_PUBLISHABLE_KEY="pk_test..." CLERK_SECRET_KEY="sk_test..." ``` -------------------------------- ### Configure Webhooks (Svix) Source: https://www.mf2.dev/docs/setup/env Set the SVIX_TOKEN for Svix webhook integration. ```bash SVIX_TOKEN="..." ``` -------------------------------- ### Run Bundle Analysis Source: https://www.mf2.dev/docs/packages/next-config Execute the build command with the ANALYZE=true environment variable to perform a bundle analysis. This helps in identifying large dependencies in your Next.js application. ```bash ANALYZE=true bun run build ``` -------------------------------- ### Initialize Server Observability Source: https://www.mf2.dev/docs/packages/observability Call this function to initialize Sentry and BetterStack on the server-side. This should be done during server startup. ```typescript import { initServerObservability } from "@repo/observability/server"; initServerObservability(); ``` -------------------------------- ### Configure Convex Backend URL Source: https://www.mf2.dev/docs/setup/env This environment variable is required for the Convex backend. The URL is automatically generated and saved to .env.local when running `bunx convex dev`. ```bash NEXT_PUBLIC_CONVEX_URL="https://your-project.convex.cloud" ``` -------------------------------- ### Configure Email (Resend) Source: https://www.mf2.dev/docs/setup/env Set the RESEND_TOKEN and RESEND_FROM environment variables for email functionality. ```bash RESEND_TOKEN="re_..." RESEND_FROM="noreply@yourdomain.com" ``` -------------------------------- ### Direct Use of Upstash Redis Client Source: https://www.mf2.dev/docs/packages/rate-limit Accesses the configured Upstash Redis client directly for custom caching operations. This allows for manual setting and getting of key-value pairs with optional expiration. ```typescript import { redis } from "@repo/rate-limit"; await redis.set("key", "value", { ex: 60 }); const value = await redis.get("key"); ``` -------------------------------- ### Bundle Analysis Source: https://www.mf2.dev/docs/commands Performs bundle analysis for the project. Set the ANALYZE environment variable to true to enable this. ```bash bun run analyze ``` -------------------------------- ### Update shadcn/ui Components Source: https://www.mf2.dev/docs/commands Updates all shadcn/ui components in the design system to their latest versions using `bunx shadcn@latest add --all --overwrite`. Be aware this overwrites customizations in `packages/design-system/components/ui/`. ```bash bun run bump-ui ``` -------------------------------- ### Sync Environment Variables Source: https://www.mf2.dev/docs/commands Synchronizes environment variables to Vercel and Convex. ```bash bun run env:push ``` -------------------------------- ### Configure CMS (BaseHub) Source: https://www.mf2.dev/docs/setup/env Set the BASEHUB_TOKEN for BaseHub CMS integration. ```bash BASEHUB_TOKEN="bshb_..." ``` -------------------------------- ### Lint and Format Check Source: https://www.mf2.dev/docs/commands Runs lint and format checks across the project using Ultracite (Biome). ```bash bun run check ``` -------------------------------- ### Route Grouping for URL Organization Source: https://www.mf2.dev/docs/colocation Demonstrates how route groups, using parenthesized folder names, organize code without affecting the URL structure. ```tree apps/app/src/app/ ├── (auth)/ # /login, /register — no "(auth)" in URL │ ├── login/ │ └── register/ ├── (app)/ # /dashboard, /settings — authenticated routes │ ├── dashboard/ │ └── settings/ └── layout.tsx # Root layout wraps everything ``` -------------------------------- ### Import Stripe SDK Source: https://www.mf2.dev/docs/packages/payments Import the raw Stripe SDK from the @repo/payments package for direct API access. This is useful for server-side operations outside of Convex. ```typescript import { stripe } from "@repo/payments"; const prices = await stripe.prices.list({ product: productId }); ``` -------------------------------- ### Configure Collaboration (Liveblocks) Source: https://www.mf2.dev/docs/setup/env Set the LIVEBLOCKS_SECRET for Liveblocks collaboration features. ```bash LIVEBLOCKS_SECRET="sk_..." ``` -------------------------------- ### Add Web Search Tool Source: https://www.mf2.dev/docs/packages/ai Integrate Perplexity-powered web search as a tool for AI agents. Ensure the PERPLEXITY_API_KEY environment variable is set. ```typescript import { getSearchTool } from "@repo/ai/tools/search"; const search = getSearchTool(); ``` -------------------------------- ### Build Single App Source: https://www.mf2.dev/docs/commands Builds a specific application within the monorepo, filtering by its name. ```bash turbo build --filter=app ``` -------------------------------- ### Configure HTTP Router for Webhooks Source: https://www.mf2.dev/docs/packages/backend Set up an HTTP router using `httpRouter` from `convex/server` to handle incoming webhooks, such as those from Clerk. ```typescript import { httpRouter } from "convex/server"; const http = httpRouter(); http.route({ path: "/clerk", method: "POST", handler: clerkWebhook, }); ``` -------------------------------- ### Run All Tests Source: https://www.mf2.dev/docs/commands Executes all tests in the monorepo using the Vitest testing framework. ```bash bun run test ``` -------------------------------- ### Import Pre-configured Model Constants Source: https://www.mf2.dev/docs/packages/ai Access pre-configured model constants and provider options for various AI models. This snippet shows importing constants for Claude and Gemini models. ```typescript import { CLAUDE_SONNET, GEMINI_FLASH, CHAT_MODELS } from "@repo/ai/models"; ``` -------------------------------- ### Run Lint and Format Checks Source: https://www.mf2.dev/docs/packages/formatting Use these commands to check code quality and apply auto-formatting. A pre-commit hook automatically runs `ultracite check`. ```bash bun run check # lint and format check ``` ```bash bun run fix # auto-fix issues ``` -------------------------------- ### Import and Use Convex API Source: https://www.mf2.dev/docs/packages/backend Import the Convex API using `@repo/backend` and use the `useAction` hook from `convex/react` to call serverless functions. ```typescript import { api } from "@repo/backend"; import { useAction } from "convex/react"; const streamChat = useAction(api.chat.streaming.send); ``` -------------------------------- ### Import and Use Base Next.js Config Source: https://www.mf2.dev/docs/packages/next-config Import the base configuration from @repo/next-config to use it directly in your Next.js app. ```typescript import { config } from "@repo/next-config"; export default config; ``` -------------------------------- ### Configure Notifications (Knock) Source: https://www.mf2.dev/docs/setup/env Set various Knock API keys and channel IDs for notification services. ```bash KNOCK_API_KEY="..." KNOCK_SECRET_API_KEY="..." KNOCK_FEED_CHANNEL_ID="..." NEXT_PUBLIC_KNOCK_API_KEY="..." NEXT_PUBLIC_KNOCK_FEED_CHANNEL_ID="..." ``` -------------------------------- ### Configure Security (Arcjet) Source: https://www.mf2.dev/docs/setup/env Set the ARCJET_KEY for Arcjet security integration. ```bash ARCJET_KEY="ajkey_..." ``` -------------------------------- ### Configure Error Tracking (Sentry) Source: https://www.mf2.dev/docs/setup/env Set SENTRY_DSN, SENTRY_ORG, and SENTRY_PROJECT for Sentry error tracking. ```bash SENTRY_DSN="https://..." SENTRY_ORG="your-org" SENTRY_PROJECT="your-project" ``` -------------------------------- ### Link Vercel Projects Before Pushing Environment Variables Source: https://www.mf2.dev/docs/setup/env Before syncing environment variables with `env:push`, link each application to its respective Vercel project. This ensures variables are correctly targeted during the push operation. ```bash cd apps/app && vercel link && cd ../.. cd apps/web && vercel link && cd ../.. ``` -------------------------------- ### Integrate Liveblocks Collaboration Provider Source: https://www.mf2.dev/docs/packages/collaboration Wrap your collaborative pages with the CollaborationProvider to enable features like avatar stacks and live cursors. Ensure you have the necessary imports from @repo/collaboration. ```tsx import { LiveCursors, AvatarStack, usePresence } from "@repo/collaboration"; import { CollaborationProvider } from "@repo/collaboration"; // Wrap collaborative pages with the provider ``` -------------------------------- ### Wrap App with NotificationProvider Source: https://www.mf2.dev/docs/packages/notifications Wrap your application with `NotificationProvider` to enable real-time notification delivery. Pass the `userId` to the provider. ```tsx import { NotificationProvider } from "@repo/notifications"; export default function RootLayout({ children }: { children: React.ReactNode }) { return ( {children} ); } ``` -------------------------------- ### Apply General Security Rules with Middleware Source: https://www.mf2.dev/docs/packages/security Use the `secure` function to apply global security rules like rate limiting and bot protection. Configure `max` requests and `window` duration for rate limiting. ```typescript import { secure } from "@repo/security"; export default secure({ rateLimit: { max: 100, window: "1m", }, botProtection: true, }); ``` -------------------------------- ### Initialize Client Observability Source: https://www.mf2.dev/docs/packages/observability Call this function to initialize Sentry and BetterStack on the client-side. Ensure it's called early in your application's lifecycle. ```typescript import { initClientObservability } from "@repo/observability/client"; initClientObservability(); ``` -------------------------------- ### Create Subscription Checkout Session Source: https://www.mf2.dev/docs/packages/payments Create a checkout session for subscriptions using the `StripeSubscriptions` client. This action requires user authentication and creates or retrieves a Stripe customer. ```typescript import { StripeSubscriptions } from "@convex-dev/stripe"; import { components } from "../_generated/api"; const stripeClient = new StripeSubscriptions(components.stripe, {}); export const createSubscriptionCheckout = action({ args: { priceId: v.string() }, handler: async (ctx, args) => { const identity = await ctx.auth.getUserIdentity(); if (!identity) throw new Error("Not authenticated"); const customer = await stripeClient.getOrCreateCustomer(ctx, { userId: identity.subject, email: identity.email, name: identity.name, }); return stripeClient.createCheckoutSession(ctx, { priceId: args.priceId, customerId: customer.customerId, mode: "subscription", successUrl: `${getAppUrl()}/settings/billing?success=true`, cancelUrl: `${getAppUrl()}/settings/billing?canceled=true`, subscriptionMetadata: { userId: identity.subject }, }); }, }); ``` -------------------------------- ### Configure Analytics (Google) Source: https://www.mf2.dev/docs/setup/env Set the NEXT_PUBLIC_GA_MEASUREMENT_ID for Google Analytics 4. ```bash NEXT_PUBLIC_GA_MEASUREMENT_ID="G-..." ``` -------------------------------- ### Import Stripe Agent Toolkit Source: https://www.mf2.dev/docs/packages/payments Import the Stripe Agent Toolkit for AI-powered payment operations. This toolkit can be used to build intelligent payment processing logic. ```typescript import { paymentsAgentToolkit } from "@repo/payments/ai"; ``` -------------------------------- ### Directory Structure for Colocation Source: https://www.mf2.dev/docs/colocation Illustrates the colocation of components within route folders, including dashboard-specific, route group, and shared authentication components. ```tree apps/app/src/app/ ├── dashboard/ │ ├── page.tsx │ ├── layout.tsx │ └── _components/ # Dashboard-specific components │ ├── stats-card.tsx │ └── recent-activity.tsx ├── settings/ │ ├── page.tsx │ └── _components/ # Settings-specific components │ └── settings-form.tsx └── (auth)/ ├── login/ │ ├── page.tsx │ └── _components/ # Login-specific components │ │ └── login-form.tsx │ ├── register/ │ │ ├── page.tsx │ │ └── _components/ # Register-specific components │ │ └── register-form.tsx │ └── _components/ # Shared across all auth routes │ └── social-buttons.tsx ``` -------------------------------- ### Add New shadcn/ui Components Source: https://www.mf2.dev/docs/packages/design-system Use the shadcn/ui CLI to add new components to the shared design system package. This command adds the 'calendar' component. ```bash bunx shadcn@latest add calendar -c packages/design-system ``` -------------------------------- ### Enable Dark Mode with ThemeProvider Source: https://www.mf2.dev/docs/packages/design-system Wrap your application's root layout with the ThemeProvider to enable dark mode and system theme detection. This component uses CSS variables for theming. ```tsx import { ThemeProvider } from "@repo/design-system/components/theme-provider"; export default function RootLayout({ children }: { children: React.ReactNode }) { return ( {children} ); } ``` -------------------------------- ### Create Stripe Customer Portal Session Source: https://www.mf2.dev/docs/packages/payments Generate a URL for the Stripe customer portal, allowing users to manage their subscriptions and billing information. ```typescript const { url } = await stripeClient.createCustomerPortalSession(ctx, { customerId: customer.customerId, returnUrl: `${getAppUrl()}/settings/billing`, }); ``` -------------------------------- ### Configure Locale Middleware Source: https://www.mf2.dev/docs/packages/i18n Set up the `i18nMiddleware` to handle locale detection and routing for your application. Configure the default locale and an array of supported locales. ```ts import { i18nMiddleware } from "@repo/internationalization"; export default i18nMiddleware({ defaultLocale: "en", locales: ["en", "es", "fr", "de", "ja"], }); ``` -------------------------------- ### Configure Rate Limiting for Specific Routes Source: https://www.mf2.dev/docs/packages/security Use the `rateLimit` function to create a limiter for specific routes. The `protect` method on the limiter determines if a request should be allowed or denied based on configured limits. ```typescript import { rateLimit } from "@repo/security"; const limiter = rateLimit({ max: 5, window: "15m", }); export async function POST(request: Request) { const decision = await limiter.protect(request); if (decision.isDenied()) { return new Response("Too many requests", { status: 429 }); } // Handle request } ``` -------------------------------- ### Server Component Page with Client Component Card Source: https://www.mf2.dev/docs/colocation Shows a Server Component page fetching data and passing it to a Client Component for interactive rendering. Ensure client interactivity is pushed to the `_components/` folder. ```tsx import { StatsCard } from "./_components/stats-card"; export default async function DashboardPage() { const stats = await getStats(); // Server: fetch data return ; // Client: render interactive UI } ``` ```tsx "use client"; export function StatsCard({ data }: { data: Stats }) { const [expanded, setExpanded] = useState(false); // Client-side interactivity lives here } ``` -------------------------------- ### Wrap App with AnalyticsProvider Source: https://www.mf2.dev/docs/packages/analytics Wrap your application with the AnalyticsProvider to enable analytics tracking. This should be done at the root of your app. ```tsx import { AnalyticsProvider } from "@repo/analytics"; export default function RootLayout({ children }: { children: React.ReactNode }) { return ( {children} ); } ```