Skip to main content
RapidDev - Software Development Agency
V0 TemplatesLanding PageIntermediate to customize

Drannel Website V0 Template: Agency Portfolio with Contact Form — The Complete Guide

The Drannel Website template is a multi-section agency portfolio built on Next.js, Tailwind CSS, shadcn/ui, and Framer Motion. It delivers a full-viewport hero, a project grid with hover effects, a services section, an about panel, and a contact form with an API route. The prompt pack wires the form to Resend email, adds a Supabase leads table with Slack notification, and adds password-protected case study pages.

Landing PageIntermediate~5 minutes

Best for

Digital agency, creative studio, or freelance developer who needs a multi-section brand website with a portfolio/work showcase and contact form — presentable to clients within hours of forking.

Stack

Next.jsTailwind CSSshadcn/uiFramer MotionLucide React

A ready-made Drannel Website UI you can fork, run, and customize with the prompt pack below.

What's actually inside

The honest engineer's breakdown — what the Drannel Websitetemplate does, how it's wired, and where it's opinionated.

The Drannel Website template is a complete agency web presence in a single Next.js project. The NavBar is fixed and includes the agency logo, anchor links to every section (Work, About, Services, Contact), and an optional CTA button. The HeroSection opens the page with full-viewport display type, a brief tagline, and an animated gradient or mesh background — the kind of opening that earns a second scroll.

WorkGrid is the centrepiece: a responsive masonry or 3-column grid of project cards, each showing an image thumbnail, project name, and category tag. The brief calls for hover-reveal overlays using Tailwind group-hover utilities. ServicesSection lists 3-4 service offerings with a Lucide icon, title, and 2-3 line description per block. AboutSection uses a two-column layout — photo or illustration on the left, bio copy and skills tags on the right. ContactForm closes the page with name, email, and message fields built from shadcn/ui Form components, wired to a Next.js API route.

Honest caveat: the ContactForm API route path is a known failure point for non-technical users. V0 sometimes scaffolds the route at app/api/contact/route.ts while the fetch in the form component references /api/contact-form — a trailing-word mismatch that causes silent 404 failures in production. This is the first gotcha below and the most important one to check before you share the live URL with a client.

Key UI components

NavBar

Fixed navigation with logo, anchor links to all page sections, and an optional CTA button.

HeroSection

Full-viewport opening with large display type, tagline, and animated gradient or mesh background.

WorkGrid

Responsive masonry or 3-column grid of project cards with image thumbnail, name, and category tag.

ServicesSection

3-4 service offering blocks with a Lucide icon, title, and 2-3 line description each.

AboutSection

Two-column layout: photo or illustration left, bio copy and skills tags right.

ContactForm

Name, email, message fields using shadcn/ui Form, wired to a Next.js API route handler.

FooterSection

Social links and copyright — minimal to keep focus on the contact form above it.

Libraries it leans on

framer-motion

Scroll-triggered entrance animations on WorkGrid cards and section headings (fade + translateY).

shadcn/ui

Card, Button, Input, Textarea, and Form — structural atoms for project cards and the ContactForm.

Lucide React

Icons for each service offering in ServicesSection.

Fork it and get it running

Forking the Drannel Website template takes about five minutes in V0. You can update the agency name, hero headline, and brand color before you even write your first prompt.

1

Open the template in V0

Navigate to https://v0.dev/chat/community/Tc4iM9HNx3M and review the full page layout in the V0 preview. Scroll from the HeroSection down through WorkGrid, ServicesSection, AboutSection, and ContactForm to confirm all sections render. Pay attention to the WorkGrid card hover states — they should reveal an overlay on hover.

Tip: Note the placeholder project images in WorkGrid — you'll replace these in Step 4.

You should see: All sections (Hero, WorkGrid, Services, About, Contact, Footer) render correctly with Framer Motion entrance animations playing on scroll.

2

Fork the project

Click the Fork button in the top-right area of the V0 editor toolbar. V0 creates a personal copy of the project attached to your account and opens it in the chat interface. Your copy is isolated — all edits are safe and cannot affect the community original.

You should see: V0 opens your forked project with a new project name in the header and the full editor and preview available.

3

Update agency name and brand in Design Mode

Press Option+D (Mac) to enter Design Mode. Click the agency name in NavBar and the hero headline in HeroSection to edit them directly. Update the primary brand color using the Themes panel. These edits cost zero credits and immediately make the template feel like your agency's own site.

Tip: Update the NavBar logo text and the footer copyright line in the same Design Mode session to avoid inconsistent branding across the page.

You should see: Agency name, hero headline, and primary brand color are updated across the page without spending any credits.

4

Replace WorkGrid placeholder images

Click into the code editor panel and locate the <Image /> tags inside WorkGrid project cards. Replace each src value with a real project screenshot URL — either self-hosted, from your CDN, or from Unsplash. Each src you change requires its domain to be listed in next.config.ts under images.remotePatterns before the Vercel deployment can optimise it (see Gotchas).

Tip: Ask V0: 'Update the remotePatterns in next.config.ts to include [your image domain].' It will add the entry automatically.

You should see: WorkGrid shows real project screenshots instead of placeholder images in the preview.

5

Publish to production

Click Share in the top-right of the V0 editor, open the Publish tab, and click 'Publish to Production'. Deployment completes in approximately 30 seconds. Before you share the URL with a client, test the ContactForm: submit a real message and check whether the API route responds (Gotcha 3 below explains the path-mismatch failure).

Tip: If the ContactForm submit returns a 404, check that the fetch URL in the form component matches the exact folder path under app/api/.

You should see: A live .vercel.app URL is returned; all sections render and the ContactForm posts without a 404.

6

Add email delivery and connect a custom domain

To send ContactForm submissions to a real inbox, open the Vars panel in V0 and add RESEND_API_KEY (or your preferred email provider key). Redeploy via Share → Publish → Publish to Production. For a custom domain, open the Vercel Dashboard from the project menu → Domains → Add domain → follow the DNS record instructions.

You should see: ContactForm submissions reach your inbox and the site is live on your custom domain with SSL.

The prompt pack

Copy-paste these straight into v0's chat to customize the Drannel Websitetemplate. Each one names this template's own components — no generic filler.

1

Replace WorkGrid placeholders with real project screenshots

Swaps hardcoded placeholder images in WorkGrid for real project screenshots and fixes the remotePatterns config in a single pass.

Quick win
Paste into v0 chat
In WorkGrid, replace every placeholder <Image /> src with the real project screenshot URL I'll provide. Use next/image with the width and height props matching each card's current dimensions. Add descriptive alt text for each project. Then update next.config.ts to add a remotePatterns entry for every external image domain referenced in the new src URLs so next/image can optimise them in production.
2

Add hover-reveal overlay on WorkGrid cards

Adds a slide-up hover overlay to each WorkGrid card showing project name and a view link — using both Tailwind group-hover and Framer Motion for the reveal animation.

Quick win
Paste into v0 chat
Wrap each project card in WorkGrid with a Tailwind group class. On hover, animate an overlay that slides up from the bottom of the card showing the project name and a 'View Project' link button. Use Tailwind group-hover utilities to control the overlay's translateY transition from 100% to 0. Additionally, wrap the overlay's appearance with a Framer Motion translateY transition using a 0.2 second ease-out duration for a smooth reveal.
3

Wire ContactForm to send email via Resend

Wires ContactForm to send emails via Resend with zod validation, and explicitly aligns the fetch URL with the route path to prevent the most common ContactForm failure.

Medium
Paste into v0 chat
Create an API route at app/api/contact/route.ts that accepts POST requests with name, email, and message fields. Use the Resend SDK (@resend/node) to send the submission to a recipient email address stored in the RECIPIENT_EMAIL env var. Validate the request body with zod — all three fields are required, email must be a valid address. Return a 400 with validation errors on invalid input and a 200 with a success JSON on delivery. Store RESEND_API_KEY and RECIPIENT_EMAIL in the Vars panel. Confirm the fetch URL in ContactForm matches '/api/contact' exactly — not '/api/contact-form' or any other variant.
4

Add filterable category pills to WorkGrid

Adds category filter pills to WorkGrid with Framer Motion enter/exit animations, using stable keys so AnimatePresence works correctly when cards are filtered in or out.

Medium
Paste into v0 chat
Add a row of filter pills above WorkGrid with categories: All, Web Design, Branding, Motion. Clicking a pill filters the displayed project cards client-side by their category tag, stored in React useState. Animate card entering and leaving with Framer Motion AnimatePresence — use scale from 0.95 to 1 and opacity from 0 to 1 for enters, and reverse for exits. Give each card a key equal to the project's unique id (not the array index) so AnimatePresence tracks items correctly.
5

Store leads in Supabase and send a Slack notification

Upgrades the ContactForm backend to persist leads to Supabase and fire a Slack notification on each submission, with graceful failure handling for the notification step.

Advanced
Paste into v0 chat
Create a Supabase table named leads with columns: id (uuid), name (text), email (text), message (text), created_at (timestamptz). Update the /api/contact route handler to (1) insert the form submission into the leads table using the Supabase service role key (server-only), and (2) POST a Slack webhook notification to SLACK_WEBHOOK_URL with a formatted message showing the lead's name, email, and first 100 characters of their message. Both operations should complete before returning a 200 response — if Supabase insert fails, return a 500; if Slack notification fails, log the error but still return 200. Store SUPABASE_URL, SUPABASE_SERVICE_ROLE_KEY, and SLACK_WEBHOOK_URL in the Vars panel.
6

Add password-protected case study pages under /work/[slug]

Adds dynamic case study pages under /work/[slug] protected by a cookie-based password gate, with an unlock page that sets the session cookie on correct entry.

Advanced
Paste into v0 chat
Create a dynamic route at app/work/[slug]/page.tsx. Each slug maps to a case study object in a local data file at data/case-studies.ts — each entry has: title, client, description, and an images array. Protect all /work/* routes with a session cookie check: if the request has a cookie named case_study_access whose value matches the ACCESS_SECRET env var, render the full case study page; otherwise redirect to /work/unlock. Create the /work/unlock page with a password input form — on correct entry, set the case_study_access cookie (httpOnly, secure, sameSite strict) and redirect back to the originally requested /work/[slug] URL. Store ACCESS_SECRET in the Vars panel.

Gotchas when you extend it

The failures people actually hit when they push this template past its defaults — and the exact fix for each.

ContactForm submit returns a 404 in production — the API route path is wrong

Why: V0 sometimes scaffolds the server route at app/api/contact/route.ts but generates the client-side fetch as a POST to /api/contact-form (with a trailing '-form'). In V0 preview this often goes unnoticed; Vercel returns a 404 in production because no route matches /api/contact-form.

Fix: Open ContactForm and find the fetch URL in the submit handler. Confirm it matches the exact folder name under app/api/. If the mismatch exists, change one of them to align — prefer editing the fetch URL to match the route file.

Fix prompt — paste into v0
Audit the fetch URL in ContactForm's submit handler and confirm it exactly matches the file path of the API route. Fix any path mismatch between the client-side fetch call and the server-side route handler file.
`Module not found: Error: Can't resolve '@/components/ui/textarea'` after `npx shadcn add`

Why: V0 generates ContactForm using a Textarea component that references the new-york-v4 registry path, which may not resolve correctly with the locally installed shadcn CLI version.

Fix: Run `npx shadcn@latest add textarea`; if the registry fetch fails, copy the Textarea component source directly from ui.shadcn.com/components/textarea and paste it into components/ui/textarea.tsx.

Fix prompt — paste into v0
Fix the missing @/components/ui/textarea import by adding the shadcn Textarea component manually. Paste the component source into components/ui/textarea.tsx and ensure it matches the import path used in ContactForm.
next/image throws an error for WorkGrid placeholder image domains in Vercel production

Why: next/image requires all external image domains to be listed in next.config.ts under images.remotePatterns. The V0 preview sandbox does not enforce this, but Vercel deployment does — any unlisted domain causes a 400 error on the image optimisation endpoint.

Fix: Add a remotePatterns entry in next.config.ts for every external domain used in WorkGrid <Image /> src props, then redeploy.

Fix prompt — paste into v0
Add remotePatterns configuration to next.config.ts to allow next/image to load images from all external domains used in WorkGrid project card image sources. Include every domain present in the current src prop values.
Framer Motion causes a flash of invisible section headings on first render

Why: Server renders section headings with initial: {{ opacity: 0 }}. After hydration, Framer Motion animates them in — on slow connections users briefly see blank space where the heading should be.

Fix: Wrap the top-level AnimatePresence component with initial={false} to prevent Framer Motion from running entrance animations during the initial page hydration pass.

Fix prompt — paste into v0
Wrap the top-level AnimatePresence component with initial={false} to prevent Framer Motion from running entrance animations during the initial page hydration. This stops section headings from flashing invisible on first render.

Template vs. custom — the honest call

A forked template gets you far, fast. Here's where it holds up, and where you'll outgrow it.

The template is enough when

  • Freelancer or small agency creating a portfolio site for a client proposal or launch event.
  • Digital studio needing a polished online presence ready before a pitch meeting.
  • Hackathon team presenting a consulting offer that needs to look production-quality.
  • V0 power user building a personal creative portfolio with a work grid and contact form.

Go custom when

  • Work showcase requires a headless CMS (Contentful, Sanity) so a non-technical team can manage portfolio entries without touching code.
  • Site needs multi-language support for international clients — i18n routing requires structural changes beyond V0's standard scope.
  • Complex case study pages with interactive before/after sliders, video embeds, or embedded prototypes that V0 struggles to maintain consistently across iterative edits.
  • You need a blog with MDX-based posts and automated social preview images for every article.

If the Drannel template is your agency's actual client-facing website and you need it to stay polished through continuous content updates, RapidDev can add a CMS layer and production deployment pipeline so your team edits content without touching V0 again.

Frequently asked questions

Is the Drannel Website V0 template free to fork?

Yes. Community templates on v0.dev are free to fork. Forking uses a small number of your V0 plan credits. The template code itself has no licensing fee — the project in your account is yours.

Can I use this template commercially for a client's agency website?

Yes. V0 community templates are published under permissive terms that allow commercial use. Always verify the current v0.dev terms of service for the definitive statement, as licensing terms can evolve.

The ContactForm submit doesn't do anything in production — why?

This is almost always the API route path mismatch: the fetch in the form component references a different URL than the actual file under app/api/. Check that the fetch URL and the route folder name match exactly. The first gotcha above has a diagnostic prompt you can paste into V0 to fix it automatically.

Why does my fork break in preview after I ask V0 to update the ServicesSection?

V0's agent can strip handler functions or reset props when it rewrites adjacent sections in the same file. After any AI edit, scroll to ContactForm and test the submit — if the button no longer posts, the onClick handler was likely stripped. Use the diagnostic prompt in Gotcha 1 above to restore it.

How do I add real project images to WorkGrid?

Edit the src prop in each <Image /> tag inside WorkGrid to point to your actual project screenshot URLs. Then ask V0: 'Add remotePatterns entries to next.config.ts for these domains: [your domains].' Without that config change, next/image will throw a domain-not-allowed error in the Vercel deployment.

How do I make the ContactForm actually send me an email?

Use Prompt 3 in the pack: it builds a /api/contact route handler using the Resend SDK with zod validation and correct path alignment. Add RESEND_API_KEY and RECIPIENT_EMAIL to the Vars panel before redeploying.

Can RapidDev help me turn this template into my agency's actual website?

Yes. RapidDev works with V0-generated agency sites and can add a CMS (Sanity or Contentful), a production email pipeline for ContactForm leads, and a deployment workflow that lets you update portfolio entries without touching V0. Your existing design stays intact.

Is there a way to protect client case study pages so not everyone can see them?

Yes — Prompt 6 in the pack adds a cookie-based password gate to all /work/[slug] dynamic routes. The unlock page sets an httpOnly cookie on correct password entry and redirects to the originally requested case study. Store the ACCESS_SECRET in the Vars panel.

Outgrowing the template?

RapidDev turns v0 prototypes into production apps — real auth, database, and payments — at $13K–$25K.

Book a free consultation

30-min call. No commitment.

Want this built for you?

We ship production apps at a fixed price — $13K–$25K, 6–10 weeks, source code yours. You've seen what it takes; we do it every week.

Get a fixed-price quote

We put the rapid in RapidDev

Need a dedicated strategic tech and growth partner? Discover what RapidDev can do for your business! Book a call with our team to schedule a free, no-obligation consultation. We'll discuss your project and provide a custom quote at no cost.