maritimemarketing . agency
Gas tanker transport shipping natural gas supply generated by ai
SEO 10 Mar 2026

JavaScript SEO traps on modern maritime websites

How JavaScript-heavy maritime websites silently lose SEO visibility, and what to check on a Vue, React or Next.js maritime site to make sure search engines see what users see.

Modern maritime websites increasingly run on JavaScript frameworks. Fleet portals built in React. Port community sites in Vue. Marketing sites generated by Next.js or Nuxt. The technology choices are sensible; the SEO consequences are often invisible until rankings start to slide.

Most JavaScript SEO problems on maritime sites aren’t the frameworks themselves; they’re how the framework was implemented. The same Next.js setup can be brilliantly SEO-friendly or quietly invisible to Google depending on choices made during the build.

The fundamental problem

Google can render JavaScript, but it does so on a delay and with a budget. The first crawl of a page typically gets the raw HTML; rendering happens later. If your service page content only exists after the JavaScript has executed, Google may take days or weeks to see it or might not see it at all on lower-priority pages.

For a maritime corporate site with 50 pages, this might be tolerable. For a port community site or fleet portal with 5,000 dynamic pages, it’s a serious problem.

Five JavaScript traps to check

1. Client-side-only rendering on commercial pages. If your service or product pages are rendered entirely in the browser (CSR), the content arrives only after JavaScript executes. Use the URL Inspection tool in Search Console to check the rendered HTML view of a key service page. If the visible content is missing from the rendered HTML, you have a CSR problem.

The fix: server-side rendering (SSR) or static generation (SSG) for content pages. Next.js, Nuxt, SvelteKit and Astro all make this straightforward. Pure CSR should be reserved for genuine application-style functionality (a logged-in fleet portal dashboard), not marketing content.

2. JavaScript-rendered metadata. A surprisingly common pattern: the page title and meta description are set client-side by the framework after page load. Google sees the original (often empty or generic) values from the static HTML.

Check: view the source of a service page (right-click, view source, not inspector). The title and meta tags should be correct in the source, not just in the rendered DOM.

3. Lazy-loaded content that never loads to the bot. Image lazy loading is fine; lazy loading of important content sections is risky. If your service description loads only when the user scrolls past it, the bot may not scroll. Anything genuinely above the fold that’s lazy-loaded on a user trigger may be invisible to Googlebot.

The fix: only lazy-load content that’s genuinely below the fold and use loading="lazy" (the native attribute) which Google handles correctly. Avoid bespoke intersection observer triggers for primary content.

4. Internal links built with onClick handlers, not anchor tags. A button or div with an onClick handler that navigates to another page is invisible to Googlebot as a link. The page won’t get the link equity flow it should.

The fix: every internal navigation should be an <a href> tag, with onClick handlers if needed for analytics, but the href is the source of truth. Single-page application routers (React Router, Vue Router) handle this correctly when used properly; misuse is what causes problems.

5. Hash-based routing. URLs like /#/services/technical-management were common in early SPAs. Google ignores everything after the hash, so these URLs are all treated as the same page. Modern SPA routing should produce real URLs (/services/technical-management) using the History API.

If you see hash routing on a current maritime site, it’s a major issue and the cleanest fix is rebuilding the routing layer.

Frameworks compared, briefly

For maritime content sites:

  • Next.js / Nuxt. Strong SSR/SSG support, well-documented SEO patterns. Good defaults for marketing sites with some interactive elements.
  • Astro. Built around static generation with selective hydration, near-ideal for content-heavy maritime sites with limited interactivity needs.
  • Pure React / Vue without SSR. Avoid for content sites. Fine for genuinely interactive applications behind login.

For maritime application sites (fleet portals, voyage planners, port community systems):

  • The application interface itself doesn’t need to be indexed.
  • The marketing layer (homepage, capability pages, pricing) absolutely does and should usually be a separate site or properly server-rendered routes inside the same project.

The diagnostic checklist

Before launching or auditing a JavaScript-heavy maritime site, run through:

  1. View source on the homepage and three service pages. Is the meaningful content present in the source HTML?
  2. Use Search Console URL Inspection to check the rendered HTML matches what the user sees.
  3. Crawl the site with Screaming Frog in JavaScript rendering mode. Compare to a non-rendering crawl. Significant differences mean JavaScript dependency.
  4. Check internal links are real anchor tags, not synthetic onClick handlers.
  5. Confirm metadata is server-rendered, not client-set.

If three or more of these fail on a maritime site that depends on organic traffic, you’re losing rankings you don’t realise you’re losing. The fixes are usually framework-level configuration changes rather than rebuilds, but they need a developer who has worked closely with SEO requirements before. That overlap of skills is rarer than you’d expect, so it’s worth checking before the build starts rather than after.

For maritime brands evaluating a new platform, the question to ask the agency or developer is “how will service pages be rendered to Googlebot, and can you show me the rendered HTML on staging?” A confident answer with a working demo on staging is a green light. A vague answer about hydration and “Google handles JavaScript fine now” means you’re about to ship a site that loses rankings on day one.

Frequently asked questions

Will switching to SSR break my existing rankings?
Done properly, no. The URLs and content stay the same; only the rendering method changes. The risk is in the surrounding migration work (URL changes, template tweaks, schema regressions) that often happens at the same time. Treat the SSR move as a formal migration with a redirect map and baseline measurements.
How do I tell whether Googlebot is actually rendering my pages?
Use the URL Inspection tool in Search Console and view the rendered HTML. If your service description, schema and internal links are present in the rendered HTML for a key service page, Google is seeing them. If the rendered HTML is mostly empty with placeholders, you have a CSR problem worth fixing this quarter.
Is Astro really a better choice than Next.js for a maritime corporate site?
For a content-heavy marketing site with limited interactive elements, Astro's static-first model produces faster pages and less JavaScript by default, which helps both rankings and Core Web Vitals. Next.js wins when you genuinely need React interactivity across most pages. Most maritime corporate sites do not, even though their developers default to it.
Share

Want help putting this into practice?

We work with maritime companies on exactly this kind of programme. Tell us about yours.