Skip to content

inertia: server-side rendering (or server-rendered <head>) for public pages #535

Closed

Description

@antosubash

Context: second migration-gap sweep for porting a large production FastAPI/Celery GIS app (gis-data-portal: MinIO-hosted PMTiles/COG maps embedded cross-origin, multi-worker web + prefork Celery, TS web client + Flutter mobile client) onto SimpleModule. Verified against framework main @ ec46dc4b and smpy_modules main @ 1284466. Portal paths are given for reference.

Problem

framework/inertia/simple_module_inertia/inertia.py:136 hard-codes is_ssr=False and ignores the SSR config (config.py:25). templating.py:72 emits an empty root. As a result:

  • public pages (landing, public catalog, CMS pages) are blank to crawlers and link-unfurlers that don't run JS;
  • pagebuilder's SEO and OG tags are set with React <Head> (smpy_modules/modules/pagebuilder/pagebuilder/pages/PublicPage.tsx:92), so they only exist after hydration. Slack, LinkedIn and many crawlers never see them.

The portal is SSR today (TanStack Start: frontend/vite.config.ts:35, head at src/routes/__root.tsx:126). Moving would regress SEO and share previews.

Proposal

Two steps, so the cheap part can ship first:

  1. Server-rendered head: a head prop or contract that Inertia views fill (title, meta, OG, canonical, JSON-LD), rendered into index.html by the template on the first response. pagebuilder and news use it.
  2. Optional Inertia SSR: honour the config. Run the Inertia SSR server (Node sidecar) when enabled, fall back to CSR if it is unreachable, and document the deploy shape.

Acceptance

curl on a public pagebuilder page returns the correct <title>, og:* and canonical tags without running JS. With SSR enabled, the page body HTML is also present.

Activity

  1. antosubash commented on Oct 22, 2026

    @antosubash
    OwnerAuthor

    Step 1 (server-rendered <head>: simple_module_inertia.Head, HostSettings.public_base_url for canonical/og URLs, client re-emit on visits) shipped in #574. This issue stays open for step 2, the Node SSR sidecar.

    https://claude.ai/code/session_01M9neheZZEe3sVpDi2S3zT4

  2. antosubash commented on Oct 22, 2026

    @antosubash
    OwnerAuthor

    Closing as done with step 1: a server-rendered <head> (Head, public_base_url, OG/canonical tags, client re-emit) shipped in #574. Full SSR through a Node sidecar is deferred and tracked in #580, which has the reviewed design.

    https://claude.ai/code/session_01M9neheZZEe3sVpDi2S3zT4

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementNew feature or request

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions