Web Development

How to Deploy a Static Next.js Site on Shared Hosting

A practical guide to using Next.js App Router, static export, and Apache-friendly URLs for cPanel hosting without a Node.js runtime.

May 30, 2026 11 min readBy CWW Group

Why static export is a strong fit for shared hosting

Shared hosting is still a practical option for marketing sites, local SEO pages, and service businesses that do not need a Node.js runtime. Most cPanel and Apache environments were never built to run a long-lived Node process, and paying for a VPS or managed Node host is overkill for a site that is fundamentally a set of marketing pages, service pages, and blog posts that change a few times a month.

Next.js can generate static HTML, CSS, and JavaScript that Apache can serve directly, with no server process, no build step at request time, and no risk of a crashed Node worker taking the whole site down. The key is designing the site around static generation from the start: no server-only APIs, no runtime SSR, and no features that require a backend during page requests.

This matters more than it sounds. Teams frequently start a Next.js project assuming they can 'switch to static later,' then discover halfway through that a contact form handler, an authenticated dashboard route, or a dynamic OG image generator depends on a Node runtime. Untangling that after the fact costs far more time than planning for static export on day one.

The export settings that actually matter

Set output: "export" in next.config so the build writes deployable files into the out directory instead of relying on a Node server at request time. For Apache and cPanel, trailingSlash: true is also important because each route becomes a folder with an index.html file rather than a bare .html file Apache may not resolve cleanly.

That means a URL like /services/website-design/ maps cleanly to out/services/website-design/index.html, which Apache serves as a directory index without any rewrite rules. Without trailing slashes, you end up patching .htaccess to strip or add extensions, which is fragile and easy to break on the next deploy.

Image optimization is the other setting people miss. Next.js's built-in image optimizer requires a server process to resize images on demand, which does not exist in a static export. Set images.unoptimized: true and pre-size your images during the build (or serve them from a CDN that handles resizing), otherwise next/image will silently fail to optimize anything in production.

  • Use static data files for services, locations, and blog posts instead of a CMS that requires runtime fetches.
  • Generate every route at build time with generateStaticParams and dynamicParams = false so there is no fallback rendering path that needs a server.
  • Keep images unoptimized or pre-generated for static hosting rather than relying on the Next.js image API.
  • Upload only the contents of the out directory, never the project source, node_modules, or .next build cache.

A single catch-all route keeps content management simple

Instead of creating a folder per route, many static Next.js sites collapse the entire site into one [[...slug]] catch-all route. generateStaticParams enumerates every valid path up front — home, static pages, every service, every blog post, every city, and every city-plus-service combination — and dynamicParams = false guarantees the build fails loudly if a path is missing rather than silently 404ing in production.

This pattern scales well because adding a new page is a data change, not a routing change: append an entry to a services array or a blogPosts array, and the build automatically creates the static HTML for it. It also keeps metadata centralized, since generateMetadata can resolve title, description, canonical URL, and Open Graph tags from the same data used to render the page.

Want help applying this to your business?

Get a free, no-obligation strategy session with our team.

Book a Free Call

SEO still works without a server

Static export does not mean thin SEO. Each route can still have a unique title, meta description, canonical URL, Open Graph tags, and structured content baked into the HTML at build time — search engines see the same fully-rendered markup a server-rendered page would produce, just generated earlier.

For service businesses, the biggest win is making every important service, industry, location, and article URL a real static page that search engines can crawl without waiting for client-side routing or JavaScript execution. That includes adding JSON-LD structured data (Organization, Service, Article, FAQPage) directly into the static HTML, keeping an accurate XML sitemap that lists every generated route, and verifying canonical tags point to the trailing-slash version of each URL to avoid duplicate-content signals.

If you are deploying a multi-location service business, this is also where local SEO compounds: a static page per city, per service, indexed cleanly with no runtime dependency, is one of the most durable ways to rank for 'service + city' queries.

Deployment checklist before you go live

Before uploading a static export to shared hosting, run through a short checklist. It is far cheaper to catch these issues in a staging deploy than after Google has crawled a broken canonical or a 404 page.

  • Confirm next build with output: "export" finishes with no dynamic-route errors.
  • Spot check 5–10 generated pages in out for correct title, meta description, and canonical tag.
  • Verify .htaccess (if used) does not conflict with the trailing-slash folder structure.
  • Test 404 handling — Apache should serve a real 404 page, not redirect every miss to the homepage.
  • Re-submit the sitemap in Search Console after each deploy that adds new routes.
  • Check that forms or chat widgets that need a backend point to an external endpoint, not a Next.js API route.

When shared hosting stops being the right answer

Static export and shared hosting are a great fit until the site needs something dynamic at request time: personalized content, authenticated areas, server-side search, or real-time inventory. At that point, a managed Node host or a hybrid architecture (static marketing site plus a separate app) usually makes more sense than forcing dynamic features into a static build.

For most local service businesses, though, the marketing site, service pages, location pages, and blog rarely need that. If ongoing maintenance, monitoring, or troubleshooting becomes a burden, that is a sign to bring in a team that manages this kind of static architecture day to day rather than patching it ad hoc.

Frequently asked questions

Can a static Next.js export use a contact form without a Node.js server?

Yes. Point the form to an external endpoint — a serverless function, a form API like Formspree, or a lightweight PHP handler on the same shared host — instead of a Next.js API route, which does not exist in a static export.

Does static export hurt SEO compared to server-side rendering?

No. Search engines crawl the fully-rendered HTML either way. Static export actually tends to help Core Web Vitals scores because there is no server response time to wait on, which is itself a ranking factor.

How do I handle a route that should not be public yet?

Since dynamicParams is false, simply omit that path from generateStaticParams. It will not be built, and Apache will return a real 404 for it.

What happens if I forget trailingSlash: true on Apache hosting?

Internal links and the sitemap may point to URLs without trailing slashes while the generated files live in folders, causing 404s or unnecessary redirects that dilute crawl efficiency and waste crawl budget on large sites.

Free AI Readiness Assessment

Future-Proof Your Business with AI

Book a free 30-minute strategy session with a senior CWW consultant. We'll map your highest-ROI AI and digital opportunities — yours to keep, no obligation.

Trusted by 500+ Bay Area businesses • Avg. response time under 4 hours