Skip to content
DESIGN11 min read

Nuxt for a Marketing Website: SEO, Speed and Multilingual Setup.

ЄвгенійTech lead, 11 years in PHP / Laravel
Published
Updated

Nuxt development for a marketing website makes sense when you need fast pages with full HTML for search engines, tight control over SEO and the ability to add interactivity (a calculator, a form, an account area) without rewriting the site. For a site of five static pages and an editor who "just wants to tweak something", you will not find a simpler tool. Below we break down what exactly Nuxt gives you, how to set it up and where it is overkill.

We build our own Tochno site on Nuxt with static page generation, so we describe the setup we deal with every day. Specific versions and module names change, so check the documentation before adopting anything.

Why a marketing site needs SSG or SSR

A classic SPA on Vue or React serves an empty <div id="app"> and JavaScript draws the content in the browser. Google can execute JS, but it does so in a second wave of indexing, with a delay and not always flawlessly. Other search engines and link preview services (messengers, social networks) do not execute JS at all.

For a marketing site this is unacceptable: its main goal is to be found and shown correctly in search and on social networks. So you need HTML with the full text already in the server response. Nuxt gives you this out of the box in several modes:

ModeHow it worksWhen to choose
SSG (prerender)all pages are built into HTML at build timelanding pages, corporate sites, blogs, documentation
SSRHTML is generated on the server for each requestpersonalized pages, catalogs that change often
Hybrid (routeRules)some routes are prerendered, some rendered on requesta site with a blog plus an account area or API

A hybrid is configured declaratively in Nuxt:

// nuxt.config.ts
export default defineNuxtConfig({
  routeRules: {
    '/**': { prerender: true },       // marketing pages: static HTML
    '/api/**': { prerender: false },  // API stays dynamic
    '/account/**': { ssr: false },    // private area: SPA, no SEO needed
  },
})

For a site that changes once a week, SSG is almost always the best choice: pages are served from a CDN or plain nginx with no computation, and the response is instant.

SEO in Nuxt: what to set up and what is already there

Meta tags and canonical URLs

Nuxt has built-in useSeoMeta and useHead. Everything we describe in the page component ends up in the finished HTML:

useSeoMeta({
  title: 'Turnkey Nuxt Website Development',
  description: 'Landing pages and corporate sites: design, development, SEO.',
  ogTitle: 'Turnkey Nuxt Website Development',
  ogImage: '/og/website-development.png',
})

The rules we follow: a unique title up to 60 characters and description up to 155 for every page, a single h1, a canonical URL in a single format (with no trailing slash, or the opposite, but always the same). Duplicates and inconsistent canonical URLs are among the most common causes of "strange" problems in Search Console.

Sitemap, robots, structured data

There are ready-made modules for sitemap and robots (@nuxtjs/sitemap, @nuxtjs/robots), and for schema.org there are separate modules or your own composable that adds JSON-LD. For a marketing site we usually add:

  • Organization and WebSite on all pages;
  • BreadcrumbList on inner pages;
  • Service or Product on service pages;
  • FAQPage where the page really has a question block;
  • BlogPosting with an author for articles.

It is important that the markup matches the visible content. Markup for questions that are not on the page violates search engine rules and does more harm than good.

The Nuxt NuxtLink component renders an ordinary <a href>, so search engines see the links. It is easier to go wrong with buttons that navigate through router.push without a real address: such transitions are invisible to a crawler. All indexable transitions must be real links.

Checks before release

After the build it is useful to have an automatic check: does every HTML file have a unique title and description, a single h1, a canonical URL, and no broken internal links. We do this with a script that runs in CI, and we block the release on violations. That is cheaper than hunting for duplicates in Search Console a month after launch.

Speed: where Nuxt wins and where you can lose

Nuxt does not make a site fast automatically. It gives you tools, and the result depends on how you use them.

Images

The @nuxt/image module converts pictures to modern formats (WebP, AVIF), picks sizes for the screen and adds loading="lazy". Two rules that give the most:

  1. Do not lazy-load the first-screen image (the LCP element); on the contrary, prioritize it (fetchpriority="high").
  2. Always specify width and height to avoid layout shifts (CLS). For more on the metrics, see Core Web Vitals for Store Owners.

Fonts

Fonts most often spoil both LCP and CLS. In Nuxt the @nuxt/fonts module downloads fonts from third-party services at build time and serves them from your own domain, substitutes fallback metrics to reduce shifts and adds preload. The benefit is obvious: fewer requests to third-party domains and no blocking CSS from Google Fonts. Advice: choose no more than two or three weights and subsets only for the languages you need.

JavaScript size

This is where Nuxt loses to plain HTML. Even a static page loads Vue, the router and the Nuxt core to hydrate the page. As a benchmark, the core eats tens of kilobytes of compressed JS before your own code. What we do to keep the budget:

  • lazily hydrate heavy interactive blocks (calculator, form, cookie banner) with hydrate-on-visible and hydrate-on-idle;
  • load heavy libraries (for example form validation) only when needed, with a dynamic import;
  • do not pull in a whole UI kit, only the components we use;
  • track the bundle size in CI so regressions are visible immediately.

To be honest: if your site needs one screen of text and a form, vanilla HTML or Astro will give less JS. Nuxt wins when the site has many components, interactivity and shared logic.

Caching and CDN

For SSG it is enough to serve static files with a long Cache-Control for hashed assets (/_nuxt/*) and a short one for HTML. This can be done on nginx, Vercel or Cloudflare. Separately check that compression (gzip or brotli) is turned on: the difference in transfer size is noticeable.

Need a site that opens fast and brings in leads? We build landing pages and corporate sites on Nuxt: design, development, an SEO foundation and a speed check before launch. Turnkey Nuxt website development, from UAH 25,000.

Multilingual setup without duplicates or confusion

For a two-language site (Ukrainian and English) three things matter: URL structure, hreflang and translations.

URL structure

The most practical scheme for the Ukrainian market: the main language without a prefix, others with a prefix. That is /posluhy for Ukrainian and /en/services for English. In Nuxt i18n modules this is the prefix_except_default mode. We transliterate Ukrainian slugs into Latin using the official transliteration and write English ones in English. That keeps URLs readable and useful for search.

hreflang and canonical

Each language version links to all the others and to itself (hreflang), while the canonical URL points to the page itself. An x-default is added for the main language. An important nuance: if the English version is not ready yet, do not publish empty pages and do not serve hreflang to non-existent URLs. It is better to have a language switched off by a flag until the content is ready.

Translations and content

Non-static texts (buttons, navigation, form labels) are convenient to keep in locale JSON files. Page and article content is better placed in separate Markdown or YAML files per language so the editor can change text without touching components. Then adding a new language comes down to adding files, not changing templates.

Typical multilingual mistakes:

  • an automatic redirect by browser language, which prevents the crawler from seeing all versions (better to offer a switcher than to force redirects);
  • translating only the text, not the meta tags and alt attributes;
  • a language switcher that leads to the home page rather than the same page in another language;
  • different date and currency formats without regard to locale.

Content: where to store it

For a marketing site there are three approaches:

  1. Files in the repository (Markdown/YAML via Nuxt Content). Pros: versioning, speed, no external dependencies, full control. Con: edits go through a developer or Git.
  2. A headless CMS (Strapi, Directus, Sanity and others). Pros: a convenient editor for a non-technical person. Cons: one more system to maintain and extra costs.
  3. An admin panel on Laravel. Justified when content is closely tied to business logic (catalog, orders). Then Nuxt takes data from the Laravel API.

For a site where content changes a few times a month, the first option is the most economical: every change is a commit and an automatic rebuild. If several people edit the site every day, you cannot do without a CMS.

The link between Nuxt and Laravel is what our full-stack Laravel + Nuxt development is about, when you need more than a static site: an account area, orders, integrations.

When Nuxt is not needed

It is better to say directly when we do not recommend Nuxt:

  • A site of 3–5 pages with no interactivity and no growth plans. Static HTML or a simple generator is enough.
  • An editor who changes content and design every day on their own. WordPress or a builder will be better here, because the benefit of full code control will not justify the maintenance cost.
  • A very small budget and a need "yesterday". A builder will launch the site faster, and you can move to custom code later, when limits appear.
  • A team with no Vue experience at all. The cost of maintenance will rise. If you plan to develop the site yourself, take this factor into account.

In the remaining cases, where you need speed, your own design, SEO control and room to grow, Nuxt pays off. We compared it with other approaches for stores in the article on Laravel, OpenCart and WordPress.

Pitfalls we have run into

  • Hydration errors. If the HTML from the server does not match what the client renders (random values, Date.now(), dependencies on window), Vue issues a warning and may repaint the page. We move browser-dependent data into onMounted or <ClientOnly>, but only for non-indexed content.
  • Content only on the client. Everything that must be indexed has to be in the HTML. The check is simple: open "View page source" (not the inspector) and find your text.
  • Trailing slashes and duplicate URLs. /posluhy and /posluhy/ are different addresses for a search engine. Choose one format, and set up a redirect at the server level and a canonical URL.
  • Third-party scripts. Analytics, chats and widgets can eat the entire speed gain. Load them after user consent and deferred.
  • Preview environments in the index. Close test and preview deployments from indexing (noindex), otherwise the search engine will find duplicates of your site.

Checklist before launching a Nuxt site

  1. The page source contains the full text and a single h1.
  2. Unique title and description on every page.
  3. Canonical URLs in a single format, redirect from trailing slashes set up.
  4. sitemap.xml and robots.txt work in production and close off test environments.
  5. Structured data passes the Rich Results Test.
  6. Images in modern formats, the first-screen image not lazy-loaded, dimensions set.
  7. Fonts served from your own domain with fallback metrics.
  8. Lighthouse on mobile, not on desktop; real CWV data is added after launch from Search Console.
  9. Forms and buttons work without JS or have a fallback path (a messenger link, mailto).
  10. Language versions link to each other, and there are no empty languages.

If you already have a Nuxt site and have doubts about it, the first step is a code audit or an express check of speed and indexing.

Planning a site or a rewrite on Nuxt? Describe the task in the brief: we will tell you whether you really need Nuxt and give an estimate within 1 business day. Fill in the brief.

AUTHORЄвгенійFounder and tech lead of Tochno. 11 years in PHP / Laravel, dozens of online store audits. Writes about what he sees in real projects.About the team

Quick answers

Didn't find an answer? Message us on Telegram.

Is Nuxt good for SEO?

Yes: Nuxt serves ready-made HTML through SSG or SSR, so search engines and AI bots see all the content right away. Meta tags, canonical URLs, a sitemap and hreflang still need to be set up, but the tools exist. Without that setup, any framework gives mediocre results.

How much does a Nuxt website cost?

A Nuxt landing page from us starts from UAH 25,000 and takes 2–3 weeks. A corporate website starts from UAH 60,000 and usually takes 5–7 weeks. The final price depends on the number of pages, languages, integrations and design complexity. We give an exact figure after a short brief.

What is the difference between SSG and SSR in Nuxt?

SSG generates pages ahead of time during the build, while SSR builds them on the server for every request. For a marketing site that rarely changes, SSG is simpler, faster and cheaper to host. SSR makes sense when content changes often or depends on the user.

When is Nuxt not needed?

If you need a simple business card site, or a site that is edited daily without a developer, WordPress or a site builder will be more practical. Nuxt is justified when speed, SEO, multiple languages and control over the code matter. Choose by real needs, not by technology fashion.

Recognise your project?

Describe your task in the brief — we'll reply with an estimate and a plan within one business day.

What you need

By submitting the form you agree to the privacy policy.