Next.js Marketing Sites: SEO and Speed Mistakes Teams Keep Making
Next.js marketing sites often launch with hidden SEO and speed problems. Here are 8 common mistakes—rendering, metadata, images, fonts—and how to fix each.
# Next.js Marketing Sites: SEO and Speed Mistakes Teams Keep Making
Next.js has become one of the most popular ways to build marketing websites. It's fast when configured correctly, it supports server-side rendering, and it plays well with modern design systems. Agencies recommend it. Developers love it. And so marketing teams end up with Next.js sites — sometimes without fully understanding what that means for search performance.
The problem is that Next.js gives you a lot of power, and power requires good decisions. Make the wrong choices — about rendering modes, metadata, image handling, or JavaScript loading — and your site can rank poorly, load slowly, and frustrate visitors, all while looking polished in a local preview.
This post covers the most common SEO and speed mistakes that keep showing up on Next.js marketing sites, with practical fixes for each one.

Why Next.js Marketing Sites Fail in Ways Other Sites Don't
A WordPress site that's slow is slow for obvious reasons: too many plugins, a bad host, unoptimized images. The problems are visible and well-documented.
Next.js problems are subtler. The framework is sophisticated enough that a site can look and feel fast — instant navigation, smooth transitions — while scoring poorly on the metrics Google actually measures. Worse, many Next.js mistakes are invisible in development. They only surface in production, or when you run a proper audit.
Mistake 1: Using Client-Side Rendering for Pages That Need to Be Indexed
This is the single biggest SEO mistake on Next.js marketing sites.
Next.js supports multiple rendering strategies. When you fetch data inside a useEffect hook — a common React pattern — that content renders only in the browser, after JavaScript loads. Googlebot can technically execute JavaScript, but it doesn't always do so reliably, and it doesn't prioritize client-rendered content the same way it prioritizes server-rendered HTML.
Marketing landing pages, service pages, and blog posts should never be client-rendered. Their content needs to be in the initial HTML response.
What to look for: View your page source (not the browser inspector — the actual source). If your content area is empty or contains only a loading spinner in the raw HTML, the page is client-rendered and probably not being indexed correctly.
The fix: Use getStaticProps (Pages Router) or mark the component as a Server Component (App Router) so content is baked into the HTML at build time or render time. If the content changes frequently, use getServerSideProps or revalidation.
Mistake 2: Missing or Incorrect Metadata
Next.js doesn't automatically generate useful metadata for you. You have to write it explicitly — and many teams don't, or do it wrong.
The most common failures:
- Every page shares the same
(usually the site name) is either missing or identical across pages- Open Graph tags (
og:title,og:description,og:image) are absent, so social shares look broken - The canonical URL isn't set, causing duplicate-content issues when query parameters are involved
Google uses your title tag as the primary signal for what a page is about. If every page on your site says "Acme Co | Home," you're making the algorithm's job harder and your click-through rates worse.
What to look for: In Next.js App Router, metadata is defined via the metadata export or generateMetadata function in each page.tsx. In Pages Router, it's done through next/head. If your team hasn't explicitly set these on every key page, they're probably missing.
The fix: Create a metadata template and apply it consistently. Each page should have a unique title (50–60 characters), a unique description (120–160 characters), and complete Open Graph tags. For blog posts and articles, add structured data per Google's article schema guidelines.
Quick checklist:
- [ ] Unique
on every page - [ ] Unique
on every page - [ ]
og:title,og:description,og:imageon every page - [ ]
set correctly - [ ] Structured data for blog posts and landing pages
Mistake 3: Shipping Too Much JavaScript

A marketing site doesn't need the same JavaScript payload as a complex web application. But Next.js makes it easy to import large component libraries, animation packages, and third-party tools that balloon the bundle size.
The result: Total Blocking Time (TBT) and Time to Interactive (TTI) scores suffer, real users on average mobile connections wait longer than they should, and your Core Web Vitals scores — which Google uses as a ranking signal — fall below acceptable thresholds.
What to look for: Run your site through Google's PageSpeed Insights or check the Core Web Vitals documentation. Look at the "Reduce unused JavaScript" and "Avoid enormous network payloads" opportunities. If your JS bundle is over 300KB compressed for a marketing page, something is wrong.
Common culprits:
- Importing entire icon libraries when you use three icons
- Loading animation libraries (Framer Motion, GSAP) on pages that barely animate
- Including a full date-formatting library when a one-liner would do
- Third-party scripts (chat widgets, analytics) loaded synchronously in
The fix: Use Next.js's built-in next/dynamic for components that don't need to be in the initial render. Audit your package.json and remove dependencies that aren't earning their weight. Move third-party scripts to load with strategy="afterInteractive" or strategy="lazyOnload" using the next/script component.
Mistake 4: Unoptimized Images
Next.js ships with a built-in component that automatically handles lazy loading, responsive sizes, and format conversion (WebP, AVIF). It's one of the framework's best features.
A surprising number of teams don't use it. They use a standard tag instead — either out of habit or because they're copying HTML from a design file — and lose all those optimizations instantly.
Others do use next/image but configure it incorrectly: missing width and height props, setting priority={true} on elements that aren't above the fold, or skipping the sizes attribute so the browser downloads a 2000px-wide image for a 300px-wide slot.
What to look for: In PageSpeed Insights, watch for "Serve images in next-gen formats," "Properly size images," and "Image elements do not have explicit width and height." These are fixable in minutes with proper next/image usage.
The fix: Replace raw tags with next/image. Always include width, height, and a meaningful alt attribute. Use priority={true} only for the largest image above the fold (your hero image). Use sizes to tell the browser the actual rendered size at each breakpoint.
Mistake 5: No `robots.txt` or `sitemap.xml`
This sounds basic, but Next.js doesn't generate either file by default.
Teams often launch a site, add pages over several months, and never create a sitemap — so Google either discovers pages slowly via crawl or misses them entirely. In the Pages Router era, you had to build these manually. In App Router (Next.js 13.3+), you can export a sitemap.ts file, but you still have to write it.
What to look for: Go to yourdomain.com/sitemap.xml and yourdomain.com/robots.txt. If either returns a 404, it's not set up.
The fix: In App Router, create src/app/sitemap.ts that returns your routes and submit the URL to Google Search Console. For robots.txt, create src/app/robots.ts or a static file in the /public directory.
Mistake 6: Slow Font Loading
Custom fonts add visual personality but are a common source of layout shift (CLS) and render delays.
The wrong approach: linking to Google Fonts via a tag in _document.tsx. This forces the browser to do a cross-origin DNS lookup, download the CSS, then download the font files — all before text can render.
Next.js 13+ includes next/font, which downloads fonts at build time, self-hosts them, and eliminates the render-blocking request entirely. Teams that aren't using it are leaving performance on the table.
The fix: Replace any with next/font/google. The API is nearly identical but the performance characteristics are dramatically better. Set display: 'swap' to ensure text is visible immediately while the custom font loads.
Mistake 7: No Structured Data on Key Pages

Structured data (Schema.org JSON-LD) helps Google understand what your page is about and can unlock rich results in search — FAQ dropdowns, article bylines, star ratings. It doesn't directly boost rankings in the traditional sense, but it increases click-through rate, which does.
Marketing sites almost never implement it, despite the relatively low effort involved.
What to look for: Use Google's Rich Results Test on any page. If the tool finds no structured data, you're missing an opportunity.
Pages that benefit most:
- Blog posts:
ArticleorBlogPostingschema - FAQ sections:
FAQPageschema - Local businesses:
LocalBusinessschema - Service pages:
Serviceschema
The fix: Add a block to relevant pages. In Next.js App Router, this can go directly in your page.tsx. In the Pages Router, inject it via next/head.
Mistake 8: Ignoring Core Web Vitals on Mobile
Most teams test their Next.js site on a fast desktop connection and call it done. Mobile is where your users are and where Google primarily evaluates performance.
The three Core Web Vitals — Largest Contentful Paint (LCP), Cumulative Layout Shift (CLS), and Interaction to Next Paint (INP) — are measured on real user devices with real network conditions. A site that scores 95 on Lighthouse desktop can score 55 on mobile if images aren't properly sized, fonts aren't preloaded, or layout shifts happen during rendering.
What to look for: In Google Search Console, go to "Core Web Vitals" under the Experience section. This shows real-world data from actual users — not simulated scores. Check the mobile report specifically.
Common mobile failures on Next.js sites:
- LCP above 2.5s (usually a large hero image without
priorityloading) - CLS above 0.1 (usually images without explicit dimensions, or fonts shifting text on load)
- INP above 200ms (usually heavy JavaScript executing on the main thread)
A Real-World Walkthrough
Here's a scenario that plays out regularly.
A software company rebuilds its marketing site on Next.js with a design agency. The site looks excellent — smooth scroll animations, a custom typeface, interactive demos on the product pages. It launches to good internal reviews.
Three months later, the marketing team notices organic traffic is flat. Competitor sites that look worse are outranking them.
An audit reveals:
- The homepage hero section uses
useEffectto fetch testimonials. The testimonials don't appear in the page source. Google is indexing an empty content area. - The animation library (Framer Motion) adds 180KB to every page, including pages with no animations.
- Fonts are loaded from Google Fonts via a
tag. CLS is 0.18 — above Google's "needs improvement" threshold. - Images on the features page use raw
tags. None are in WebP format. Average image payload is 2.1MB. - There's no
sitemap.xml. Three service pages launched two months ago have never been indexed.
None of these require a site rebuild. Each fix takes hours, not weeks. But because no one audited the site at launch, they compounded for three months.

Your Next.js Marketing Site Checklist
Use this before launch, and run it again every quarter.
Rendering & Indexability
- [ ] All marketing pages render content in the initial HTML (not behind
useEffect) - [ ] View page source on key pages and confirm content is present
- [ ] Check Google Search Console for "crawled but not indexed" errors
Metadata
- [ ] Unique title tags on every page (50–60 characters)
- [ ] Unique meta descriptions on every page (120–160 characters)
- [ ] Open Graph tags set on all pages
- [ ] Canonical URLs set correctly
Performance
- [ ] JavaScript bundle under 300KB compressed per page
- [ ] All images use
next/imagewith explicit width/height and alt text - [ ] Hero image uses
priority={true} - [ ] Fonts loaded via
next/font, not a Google Fontstag - [ ] Third-party scripts use
next/scriptwith a deferred loading strategy - [ ] Core Web Vitals pass in Google Search Console (mobile report)
Crawlability
- [ ]
sitemap.xmlexists and is submitted to Search Console - [ ]
robots.txtis configured correctly - [ ] No important pages blocked by
noindexaccidentally
Structured Data
- [ ] Blog posts have
Articleschema - [ ] FAQ sections have
FAQPageschema - [ ] Local business info has
LocalBusinessschema (if applicable)
Run a Free Audit on Your Next.js Site
If you're not sure which of these issues apply to your site, the fastest way to find out is a direct audit.
FreeSiteAudit checks your pages for rendering problems, missing metadata, image issues, Core Web Vitals failures, and more — and gives you a prioritized list of what to fix first. No account required for the free check.
Run a free audit at FreeSiteAudit →
Sources
- Google Search Console Help: Creating Helpful Content — https://developers.google.com/search/docs/fundamentals/creating-helpful-content
- Google Structured Data: Article Schema — https://developers.google.com/search/docs/appearance/structured-data/article
- web.dev: Core Web Vitals — https://web.dev/articles/vitals
Related Tools
Related Fixes
Check your website for free
Get an instant score and your top 3 critical issues in under 60 seconds.
Get Your Free Audit →