Skip to main content
RapidDev - Software Development Agency
weweb-tutorial

WeWeb SEO: SPA Challenges, Meta Tags, and Prerendering Solutions

WeWeb generates single-page applications (SPAs) with no server-side rendering as of 2026. Googlebot can index JavaScript-rendered content but with delays. Social media crawlers often cannot. Fix this with per-page meta tags in Page settings → SEO & Meta Tags, Prerender.io or SEO4Ajax for crawler-facing HTML snapshots, a custom sitemap for dynamic pages, and JSON-LD structured data via App Settings → Custom Code.

What you'll learn

  • Why WeWeb SPAs have SEO limitations and what Google's crawler actually sees when it visits your site
  • How to set per-page meta tags, Open Graph tags, and structured data (JSON-LD) in WeWeb
  • How to configure your sitemap for static pages and upload a custom sitemap for dynamic collection pages
  • How to set up Prerender.io as a crawler-facing HTML snapshot service to fix social media crawlers
  • When to use a separate platform (WordPress, Webflow) for SEO-critical content vs WeWeb for the app
Book a free consultation
4.9Clutch rating
600+Happy partners
17+Countries served
190+Team members
Intermediate13 min read60-90 minWeWeb Free plan and above; Prerender.io integration requires Essential+ (custom domain required)March 2026RapidDev Engineering Team
TL;DR

WeWeb generates single-page applications (SPAs) with no server-side rendering as of 2026. Googlebot can index JavaScript-rendered content but with delays. Social media crawlers often cannot. Fix this with per-page meta tags in Page settings → SEO & Meta Tags, Prerender.io or SEO4Ajax for crawler-facing HTML snapshots, a custom sitemap for dynamic pages, and JSON-LD structured data via App Settings → Custom Code.

WeWeb SEO: Solving SPA Crawlability, Meta Tags, and Prerendering

WeWeb is a single-page application builder — it outputs a Vue.js SPA where all content is rendered client-side in the browser. As of 2026, WeWeb does not support server-side rendering (SSR) or static site generation (SSG). This creates two related SEO problems: Google can index JavaScript-rendered content but typically with a delay of days to weeks (its crawler renders JS, but not immediately on discovery); and social media crawlers (Twitter/X, Facebook, LinkedIn, Slack) generally do not execute JavaScript, meaning your Open Graph tags and content may not appear when users share links. This tutorial explains exactly what the limitations are, what you can do about them within WeWeb, and when it makes sense to use a separate platform for SEO-critical content.

Prerequisites

  • A WeWeb project published with a custom domain
  • Basic understanding of HTML meta tags and what Open Graph (OG) tags are
  • A Google Search Console account (free, at search.google.com/search-console) to monitor indexing
  • Optional: a Prerender.io account for the prerendering section

Step-by-step guide

1

Understand What Googlebot Actually Sees

WeWeb outputs an HTML file that looks like this to a crawler before JavaScript executes: a nearly empty <body> containing only a <div id='app'></div> and script tags. All your visible content, headings, and meta tags are injected by JavaScript after the page loads. Googlebot (Google's crawler) uses a Chromium-based renderer and CAN execute JavaScript — but it queues JavaScript rendering separately from initial crawl. This means: your pages will eventually be indexed, but there can be a delay of days to weeks between when Google discovers a URL and when it renders and indexes the JS-generated content. To verify what Google sees today: use Google Search Console → URL Inspection → enter your page URL → click 'Test Live URL' → click 'View tested page' → switch to 'Screenshot' tab to see the rendered page, and 'HTML' tab to see the rendered HTML including your meta tags.

Expected result: You understand the two-stage Googlebot process and can use Search Console's URL Inspection to verify your pages are indexed with correct meta tags.

2

Configure Per-Page Meta Tags

In the WeWeb editor, click on any page in the Pages panel (left sidebar). Then click the gear icon that appears next to the page name, or right-click → Page settings. Navigate to the 'SEO & Meta Tags' tab. Fill in: Title Tag (the <title> element — appears in browser tabs and Google search results, max 60 characters), Meta Description (max 155 characters — shown in search snippets), Open Graph Title (og:title — for social sharing), Open Graph Description (og:description), Open Graph Image (og:image — minimum 1200x630px, must be a full URL including https://), Twitter Card type (set to 'summary_large_image' for most pages), and the Canonical URL if needed. These fields are injected as meta tags in the page's <head> when the JS renders. They are read by Googlebot (after rendering) but NOT by social media crawlers (which do not execute JS). For static pages like your homepage and landing pages, filling these fields is sufficient for Google. For social sharing meta tags, you need Prerender.io (Step 5).

Expected result: All major pages have unique Title Tags and Meta Descriptions. Open Graph fields are populated with correct image URLs.

3

Add Structured Data (JSON-LD) via Custom Code

Structured data (Schema.org JSON-LD) helps Google understand your content type and can enable rich results (star ratings, FAQ dropdowns, product prices in search). In WeWeb, you cannot inject per-page scripts natively — structured data must go in App Settings → Custom Code → Head section, which applies to all pages. For a site with multiple page types, use a JavaScript approach: inject a single <script type='application/ld+json'> tag that reads the current URL and outputs the appropriate schema. Alternatively, for static pages like your homepage, add a static JSON-LD block. For dynamic collection pages (e.g., /products/:id), JavaScript in the Head can read the URL parameter and output dynamic structured data by constructing the schema from window.location. Note that this approach requires the data to be available at render time — which it is, since WeWeb fetches collections before rendering.

typescript
1<!-- Injection point: App Settings Custom Code Head section -->
2<!-- Static JSON-LD for homepage -->
3<script type="application/ld+json">
4{
5 "@context": "https://schema.org",
6 "@type": "WebSite",
7 "name": "Your App Name",
8 "url": "https://yourapp.com",
9 "description": "Your app description here",
10 "potentialAction": {
11 "@type": "SearchAction",
12 "target": "https://yourapp.com/search?q={search_term_string}",
13 "query-input": "required name=search_term_string"
14 }
15}
16</script>
17
18<!-- Dynamic JSON-LD for product pages (/products/:id) -->
19<!-- Reads page title and description injected by WeWeb collections -->
20<script>
21 document.addEventListener('DOMContentLoaded', function() {
22 const path = window.location.pathname;
23 // Only inject product schema on product pages
24 if (path.startsWith('/products/')) {
25 // WeWeb will have populated the page title by now
26 const title = document.title;
27 const script = document.createElement('script');
28 script.type = 'application/ld+json';
29 script.text = JSON.stringify({
30 '@context': 'https://schema.org',
31 '@type': 'Product',
32 'name': title,
33 'url': window.location.href
34 });
35 document.head.appendChild(script);
36 }
37 });
38</script>

Expected result: Structured data is injected for relevant pages. Rich Results Test shows valid schema without errors.

4

Configure Your Sitemap

WeWeb automatically generates a sitemap.xml for all your static pages. Access it at: yourapp.com/sitemap.xml. Verify it includes all your important pages and that URLs are correct. The auto-generated sitemap does NOT include dynamic collection pages (e.g., /products/123, /blog/post-title) because WeWeb has no knowledge of your backend data. For dynamic pages, you need a custom sitemap. Two approaches: (1) Generate a sitemap XML file from your backend data (Supabase query → format as XML → host at a static URL or through an Edge Function) and submit it in Google Search Console. (2) Use a service like Prerender.io's sitemap generator. To submit your sitemap to Google: Google Search Console → your property → Sitemaps → enter sitemap URL → Submit. Check the 'Discovered URLs' count matches your expected page count. Add the sitemap URL to your App Settings → Custom Code → Head: <link rel='sitemap' type='application/xml' href='/sitemap.xml'>.

typescript
1-- Injection point: Supabase Edge Function generates dynamic sitemap
2-- supabase/functions/sitemap/index.ts
3-- Set up a reverse proxy or CNAME so yourapp.com/sitemap-products.xml calls this function
4
5import { createClient } from 'https://esm.sh/@supabase/supabase-js@2';
6
7const supabase = createClient(
8 Deno.env.get('SUPABASE_URL')!,
9 Deno.env.get('SUPABASE_ANON_KEY')!
10);
11
12Deno.serve(async () => {
13 const { data: products } = await supabase
14 .from('products')
15 .select('id, updated_at')
16 .eq('status', 'active');
17
18 const urls = (products || []).map(p => `
19 <url>
20 <loc>https://yourapp.com/products/${p.id}</loc>
21 <lastmod>${p.updated_at?.split('T')[0]}</lastmod>
22 <changefreq>weekly</changefreq>
23 <priority>0.8</priority>
24 </url>`);
25
26 const xml = `<?xml version="1.0" encoding="UTF-8"?>
27<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">
28${urls.join('')}
29</urlset>`;
30
31 return new Response(xml, {
32 headers: { 'Content-Type': 'application/xml' }
33 });
34});

Expected result: WeWeb's auto-generated sitemap is submitted to Google Search Console. A custom sitemap for dynamic pages is generated and submitted separately.

5

Set Up Prerender.io for Social Media Crawlers

Prerender.io (and similar services like SEO4Ajax) work as a middleware layer: when a crawler visits your site (identified by user-agent), it is redirected to a pre-rendered HTML snapshot of your page instead of the JavaScript SPA. This snapshot includes your Open Graph meta tags, allowing link previews to work correctly on Twitter/X, Facebook, LinkedIn, and Slack. Sign up at prerender.io (free tier available with limited pages). Get your Prerender token. For WeWeb Cloud deployments, you cannot modify the CDN/edge layer directly — use Prerender.io's JavaScript snippet approach: add the Prerender snippet to App Settings → Custom Code → Head (their docs provide the script). This approach has the JS prerender snippet detect crawlers and redirect them server-side. For self-hosted WeWeb (exported code on Cloudflare), you can use Cloudflare Workers to intercept crawler requests and fetch from Prerender.io's API, which is faster and more reliable.

typescript
1<!-- Injection point: App Settings Custom Code Head section -->
2<!-- Prerender.io JavaScript snippet for crawler detection -->
3<!-- Get your token from prerender.io dashboard -->
4<script>
5 window.prerenderReady = false;
6</script>
7<script>
8 (function(w,d) {
9 // Prerender.io snippet - replace YOUR_TOKEN with actual token
10 var e = d.createElement('script');
11 e.src = 'https://cdn.prerender.io/prerender.js';
12 e.setAttribute('data-token', 'YOUR_PRERENDER_TOKEN');
13 d.head.appendChild(e);
14 })(window, document);
15</script>
16
17<!-- Signal to Prerender that page is fully rendered -->
18<!-- Add this to your On page load workflow's last Custom JavaScript action -->
19<!-- Or set it in App Settings Custom Code Body -->
20<script>
21 document.addEventListener('DOMContentLoaded', function() {
22 // Tell Prerender.io the page is ready after collections load
23 // In production, move this to a workflow action after all collections fetch
24 setTimeout(function() {
25 window.prerenderReady = true;
26 }, 2000);
27 });
28</script>

Expected result: Sharing links from your WeWeb app on Twitter/X, LinkedIn, and Slack shows correct titles, descriptions, and preview images.

6

Optimize Meta Tags for Dynamic Collection Pages

For pages using URL path parameters (e.g., /products/:id), meta tags need to be dynamic — the title and description should reflect the specific product being shown. In WeWeb, go to the dynamic page settings → SEO & Meta Tags. Instead of a static title, click the formula icon (plug icon 🔌) next to the Title Tag field and bind it to a formula using your collection: collections['currentProduct'].data[0].title + ' | Your App Name'. Similarly bind the Meta Description field to: collections['currentProduct'].data[0].description. For the Open Graph Image, bind to: collections['currentProduct'].data[0].image_url. These dynamic bindings use the JavaScript-rendered data — they are visible to Googlebot after rendering, but still invisible to social crawlers without Prerender.io. Ensure your collection is set up to fetch the product matching the URL parameter (Page URL variable :id → collection filter id = urlParam).

Expected result: Dynamic pages have unique, data-driven meta tags. Google Search Console URL Inspection shows the correct product title and description for individual product pages.

7

Consider a Separate Platform Strategy for SEO-Critical Content

For marketing sites, blogs, and other SEO-heavy content where organic search is a primary acquisition channel, WeWeb's SPA architecture is a meaningful disadvantage compared to SSR-first platforms like WordPress, Webflow, or Nuxt.js. A practical hybrid strategy: host your marketing site and blog on a subdomain (blog.yourapp.com) using WordPress or Webflow, which provide native SSR and immediate indexing with no prerendering workarounds. Host your actual application (app.yourapp.com or /app path) in WeWeb where the SPA strengths — fast navigation, rich interactions, complex state — are most valuable. Link between the two for cross-pollination of authority. This is the same strategy used by many SaaS companies: a content-rich marketing site built for SEO plus a React/Vue SPA for the product. WeWeb is the product layer, not the content layer.

Expected result: Clear strategy for which content lives in WeWeb vs a separate SEO-optimized platform, with cross-linking between them.

Complete working example

og-meta-head-injection.html
1<!-- Injection point: App Settings Custom Code Head section -->
2<!-- Comprehensive meta tag setup for WeWeb SPA -->
3<!-- Replace all placeholder values with your actual content -->
4
5<!-- Primary meta tags (also read by Googlebot after JS render) -->
6<!-- Note: These are ALSO set per-page in Page settings SEO & Meta Tags -->
7<!-- The Custom Code below handles the fallback/global defaults -->
8
9<!-- Open Graph fallback for social crawlers (static fallback only) -->
10<!-- Dynamic values require Prerender.io to be set correctly -->
11<meta property="og:site_name" content="Your App Name" />
12<meta property="og:type" content="website" />
13<meta property="og:locale" content="en_US" />
14
15<!-- Twitter Card defaults -->
16<meta name="twitter:card" content="summary_large_image" />
17<meta name="twitter:site" content="@yourhandle" />
18
19<!-- Canonical URL helper: prevents duplicate content on hash routes -->
20<script>
21 // Inject canonical URL dynamically based on current path
22 (function() {
23 function setCanonical() {
24 var existing = document.querySelector('link[rel="canonical"]');
25 if (!existing) {
26 var link = document.createElement('link');
27 link.rel = 'canonical';
28 link.href = window.location.origin + window.location.pathname;
29 document.head.appendChild(link);
30 }
31 }
32 // Run on initial load
33 if (document.readyState === 'loading') {
34 document.addEventListener('DOMContentLoaded', setCanonical);
35 } else {
36 setCanonical();
37 }
38 // Run on SPA navigation (Vue Router history change)
39 var _pushState = history.pushState;
40 history.pushState = function() {
41 _pushState.apply(history, arguments);
42 setTimeout(setCanonical, 100);
43 };
44 })();
45</script>
46
47<!-- Robots meta: adjust per environment -->
48<!-- Remove or change to 'index, follow' for production -->
49<!-- <meta name="robots" content="noindex, nofollow" /> -->
50
51<!-- Sitemap reference -->
52<link rel="sitemap" type="application/xml" href="/sitemap.xml" />

Common mistakes

Why it's a problem: Assuming that filling in WeWeb's Page settings → SEO & Meta Tags fields will fix social media link previews

How to avoid: WeWeb's meta tags are injected by JavaScript after page load. Social media crawlers (Twitter, Facebook, LinkedIn, Slack) do not execute JavaScript. Your OG tags are invisible to them. To fix social previews, you need Prerender.io or a similar HTML snapshot service. Google is the exception — it renders JS and will eventually see your tags.

Why it's a problem: Expecting the auto-generated sitemap.xml to include your dynamic collection pages (/products/123, /blog/post-slug)

How to avoid: WeWeb's sitemap only includes statically defined pages. Dynamic collection pages are not in the sitemap because WeWeb does not know which IDs exist in your database. Create a custom sitemap using a Supabase Edge Function that queries your database and generates XML, then submit it to Google Search Console separately.

Why it's a problem: Adding custom CSS in App Settings → Custom Code → Head and wondering why it does not appear in the preview

How to avoid: Custom CSS added in the Head section is NOT rendered in the WeWeb editor preview. You must publish your app to see Custom Code changes. Always publish to a staging environment (if on Scale plan) or directly to production, then check using Chrome DevTools or by viewing page source.

Why it's a problem: Setting window.prerenderReady = true too early before collections have finished loading

How to avoid: Prerender.io takes its HTML snapshot when window.prerenderReady is true. If you set it immediately on DOMContentLoaded, your content may not be loaded yet and the snapshot will be empty. Set it as the last action in your On page load workflow using a Custom JavaScript action, after all collections have been fetched.

Best practices

  • Use unique Title Tags for every page — avoid duplicate titles which dilute SEO value and confuse Google
  • Keep meta descriptions under 155 characters and make them actionable — they are your 'ad copy' in search results
  • Submit your sitemap to Google Search Console and monitor 'Crawled - currently not indexed' pages which indicate content Google has seen but not indexed
  • Use Google's URL Inspection tool in Search Console to verify each important page is indexed correctly with the right title and description
  • For pages that should never be indexed (admin panels, internal tools, login pages), add a robots meta tag: set Page settings → SEO → no-index toggle, or add <meta name='robots' content='noindex'> for those pages via a page-specific method
  • Test Open Graph previews using the LinkedIn Post Inspector (linkedin.com/post-inspector) and the Facebook Sharing Debugger (developers.facebook.com/tools/debug) after setting up Prerender.io
  • Consider structured data (FAQ schema) for any page that has a FAQ section — it can earn Google's FAQ rich result which significantly increases click-through rate

Still stuck?

Copy one of these prompts to get a personalized, step-by-step explanation.

ChatGPT Prompt

I have a WeWeb SPA (no SSR support as of 2026) with product pages at /products/:id. Each product has a title, description, and image URL stored in Supabase. Write a Supabase Edge Function that generates a dynamic sitemap.xml for all active products, formatted correctly for Google Search Console submission.

WeWeb Prompt

My WeWeb app has dynamic product pages at /products/:id with a 'currentProduct' collection that fetches by URL parameter. Help me write the formula for the Page settings → SEO & Meta Tags → Title Tag field that outputs: '[Product Name] - Buy Online | My Store', using the currentProduct collection data.

Frequently asked questions

Does WeWeb support server-side rendering (SSR) in 2026?

No. As of March 2026, WeWeb does not support SSR or static site generation (SSG). All rendering happens client-side in the browser. WeWeb's team has mentioned SSR as a future consideration, but no release date has been announced. All WeWeb apps are Vue.js single-page applications. This is the fundamental reason for the SEO limitations described in this guide.

Will Google eventually index all my WeWeb pages even without SSR?

Yes, Google's Googlebot renders JavaScript and will index your pages — but with a delay. Initial discovery happens quickly; JavaScript rendering is queued separately and can take days to weeks. Once indexed, your pages appear in search results. The main issues are: (1) the indexing delay for new content, (2) dynamic meta tags may not be read on first crawl, and (3) link previews on social platforms will not work without Prerender.io.

Can I add Google Analytics to a WeWeb site?

Yes. The recommended approach is to install the Google Tag Manager plugin: Plugins → Extensions → Google Tag Manager → enter your GTM Container ID. Then configure GA4 inside GTM. Alternatively, add the GA4 script snippet directly in App Settings → Custom Code → Head section. WeWeb SPAs require special handling for page view tracking — use GTM's History Change trigger to fire page view events on SPA navigation.

How do I stop Google from indexing certain WeWeb pages (like my admin dashboard)?

In the WeWeb editor, go to the page's Page settings → SEO & Meta Tags tab and look for the 'No-index' toggle or robots field. Set it to 'noindex, nofollow' for pages you want excluded from Google. Alternatively, add a Custom JavaScript action On page load that checks if the current page is an admin page and injects a noindex meta tag. For the most reliable exclusion, also add the page to a robots.txt Disallow rule — add your robots.txt content in App Settings → Custom Code if WeWeb does not expose a robots.txt editor directly.

RapidDev

Talk to an Expert

Our team has built 600+ apps. Get personalized help with your project.

Book a free consultation

Need help with your project?

Our experts have built 600+ apps and can accelerate your development. Book a free consultation — no strings attached.

Book a free consultation

We put the rapid in RapidDev

Need a dedicated strategic tech and growth partner? Discover what RapidDev can do for your business! Book a call with our team to schedule a free, no-obligation consultation. We'll discuss your project and provide a custom quote at no cost.