Convert HTML Template To Next JS

I’ll walk you through converting a plain HTML template into a clean Next.js (App Router) project, explain the key patterns and pitfalls, and give concrete example files you can copy-paste. I’ll assume Next.js 13+ with the app/ router (recommended).

Vivek Rastogi

8/8/20253 min read

STEP 1 — Create the Next.js app
  • npx create-next-app@latest my-site --app

  • cd my-site

  • npm run dev

This scaffolds a Next.js app using the app/ router. Open http://localhost:3000.

STEP 2 — Project structure (what we’ll create)
STEP 3 — Move Static Assets
  • Copy the images / fonts / vendor CSS / JS files from the HTML template into public/ (e.g., public/images/hero.jpg, public/fonts/...).

  • Public files are served from / (so /images/hero.jpg works).

STEP 4 — Global CSS

If your template has a main CSS file (e.g., assets/css/style.css) move it to styles/globals.css.

app/layout.jsx

Importing globals.css here ensures styles are available app-wide.

Step 5 — Convert index.html → app/page.jsx

Take the <main> part of your HTML and turn it into JSX. Remember common conversions:

  • class → className

  • for (labels) → htmlFor

  • Self-close tags: <img />, <input />

  • Replace <a href="/"> with next/link where appropriate

Example original snippet of HTML file

Converted to Next
Step 6 — Break the template into components

Create presentational components for Header, Footer, Hero, etc.

components/Header.jsx

components/Hero.jsx
Use next/image for optimized images. Put files into public/images/.

Step 7 — Handling template JavaScript (sliders, plugins, jQuery)

React/Next prefers componentized UI. Options:

A. Replace plugin with React library — e.g., use react-slick instead of initializing a jQuery slick slider.

B. If you must keep the vendor script: import it and run initialization in a client component:

C. For plain vendor scripts: include with <Script> in layout or component and initialize inside a 'use client' component useEffect.

Step 8 — Forms → Next.js API routes

If your template has a contact form submitting to contact.php, convert it to a Next API route:

app/api/contact/route.js

Then submit from the client using fetch('/api/contact', { method: 'POST', body: JSON.stringify(formData) }).

Step 9 — Routing & dynamic pages
  • Static pages → app/about/page.jsx

  • Dynamic pages → app/products/[slug]/page.jsx

  • Create generateStaticParams() in app router for static export prerendered pages if needed.

Step 10 — SEO & Head tags

In the app router, use export const metadata = { ... } in each page.jsx (or set in layout.jsx) to control <title> and meta tags.

Step 11 — Common pitfalls & fixes
  • No CSS applied: confirm import './globals.css' in app/layout.jsx and path is correct.

  • class → className: search/replace class=" → className=".

  • Inline scripts using DOM: Move DOM-manipulating code into a client component with useEffect.

  • jQuery: avoid—rewrite logic as React components or carefully include jQuery in a client-only component.

  • Third-party scripts must be client-only: use <Script src="..." strategy="lazyOnload" /> or initialize in useEffect.

  • Image 404s: ensure files are in public/ and paths start with /.

Step 12 — Deploy
  • Push to GitHub.

  • Deploy on Vercel (recommended): import repo; Vercel auto-detects Next.js.

  • Or use other hosts (Netlify, Render) — follow host instructions.

Step 13 — Example: Full minimal files (copy-paste)

app/layout.jsx

app/page.jsx
components/Footer.jsx
styles/globals.css
Step 14 — Next steps & checklist before you finish
  • Move all images to /public and replace src paths.

  • Convert all class → className.

  • Decide client or server components ('use client' where you use state/effects).

  • Replace jQuery plugins with React equivalents or wrap them carefully.

  • Convert form endpoints to app/api/* routes.

  • Validate SEO metadata, sitemap, and robots.txt if needed.

  • Test on mobile/responsive breakpoints.