Many clients already pay for a cPanel shared hosting plan, and many of those plans cannot run a Node.js server. That does not mean you have to give up React and Next.js. If the site is content-driven (a portfolio, a company profile, a blog), a static export gives you plain HTML, CSS and JavaScript files that any Apache server can serve very fast.
1. Turn on static export
In next.config.mjs set output: "export". Next.js then writes every page to the out/ folder at build time. Two more settings make life easier on Apache:
const nextConfig = {
output: "export",
trailingSlash: true, // /about/ -> /about/index.html
images: { unoptimized: true } // no image server on shared hosting
};
Dynamic routes such as /blog/[slug] still work: export the list of slugs from generateStaticParams() and every article becomes its own HTML file, which is excellent for SEO.
2. Replace API routes with PHP
Route handlers and server actions need a running Node.js server, so they are not available in a static export. Shared hosting always has PHP, so the contact form posts to a small contact.php file placed in the public/ folder (it is copied to out/ as-is). The endpoint should:
- accept only POST requests and return JSON;
- validate every field on the server: required, maximum length,
filter_var($email, FILTER_VALIDATE_EMAIL); - strip line breaks from anything that goes into a mail header, to block header injection;
- send from an address on your own domain and put the visitor in
Reply-To, otherwise SPF and DMARC will push the message to spam; - use a hidden honeypot field and a simple rate limit to stop bots without annoying people with a captcha.
3. Let Apache do the rest
An .htaccess file in the site root forces HTTPS, serves the exported 404.html for unknown URLs, sets long cache headers for the hashed files in /_next/static/ and keeps old URLs alive with 301 redirects, so the search rankings you already have are not lost.
4. Deliverability
In cPanel open Email Deliverability and make sure SPF and DKIM are valid for the domain. If the mailbox is hosted elsewhere (Microsoft 365 or Google Workspace), set Email Routing to Remote Mail Exchanger, otherwise the server will try to deliver the message locally and it never arrives.
5. Deploy
Run npm run build, upload the contents of out/ to public_html and test the form once. The result is a site that loads in milliseconds, has nothing to patch on the server side except one PHP file, and costs the client nothing extra.