Skip to content

feat(@tinacms/astro): forward containerOptions to island route container#7166

Open
dfan1028 wants to merge 1 commit into
tinacms:mainfrom
dfan1028:feat/astro-island-route-container-options
Open

feat(@tinacms/astro): forward containerOptions to island route container#7166
dfan1028 wants to merge 1 commit into
tinacms:mainfrom
dfan1028:feat/astro-island-route-container-options

Conversation

@dfan1028

@dfan1028 dfan1028 commented Jul 7, 2026

Copy link
Copy Markdown

Problem

experimental_createIslandRoute renders each island through a fresh AstroContainer created with AstroContainer.create() — no renderers. Unlike Astro's page pipeline, the container does not inherit renderers from the project's Astro config, so any island that renders a UI-framework component (React, Vue, Svelte, …) fails to render during visual editing. The island-refresh request 500s and the editor silently falls back to form-only editing (no live preview).

This doesn't affect islands that render plain Astro/markdown, which is why it hasn't surfaced in the examples/astro/visual-editing app — but it reliably bites projects that put framework components inside visually-edited regions (in our case, a React component library rendered in TinaMarkdown blocks and an interactive search island).

Fix

Add an optional containerOptions argument to experimental_createIslandRoute, forwarded to AstroContainer.create. Callers register renderers explicitly:

import reactRenderer from '@astrojs/react/server.js';

export const ALL = experimental_createIslandRoute(islands, {
  containerOptions: { renderers: [{ name: '@astrojs/react', ssr: reactRenderer }] },
});

Passing renderers explicitly (rather than auto-loading via astro:container's loadRenderers) keeps this working in a plain Node/SSR context — the astro:container virtual module only resolves inside Vite.

The argument is optional, so existing callers are unchanged.

Changes

  • island-route.ts: IslandRouteOptions type; forward options?.containerOptions to AstroContainer.create.
  • experimental.ts: export IslandRouteOptions.
  • Test: assert containerOptions is forwarded to AstroContainer.create.
  • Changeset (minor).

Validation

Verified in a downstream Astro + React project: with this change the island route renders React islands in visual editing; without it the same islands 500. I did not run the full monorepo suite locally — deferring to CI — but the added unit test follows the existing island-route.test.ts patterns.

Notes

Happy to adjust the API shape (e.g. accept renderers directly instead of the nested containerOptions) or add auto-loading behind a flag if preferred.

Made with Cursor

experimental_createIslandRoute creates its AstroContainer with no
renderers. Unlike the page pipeline, the container does not inherit
renderers from the Astro config, so islands that use a UI framework
(React, Vue, ...) fail to render in visual editing.

Add an optional containerOptions argument forwarded to
AstroContainer.create so callers can register renderers, e.g.
{ containerOptions: { renderers: [{ name: '@astrojs/react', ssr }] } }.
The argument is optional; existing callers are unaffected.

Co-authored-by: Cursor <cursoragent@cursor.com>
@changeset-bot

changeset-bot Bot commented Jul 7, 2026

Copy link
Copy Markdown

🦋 Changeset detected

Latest commit: 9631b68

The changes in this PR will be included in the next version bump.

This PR includes changesets to release 1 package
Name Type
@tinacms/astro Minor

Not sure what this means? Click here to learn what changesets are.

Click here if you're a maintainer who wants to add another changeset to this PR

@CLAassistant

CLAassistant commented Jul 7, 2026

Copy link
Copy Markdown

CLA assistant check
All committers have signed the CLA.

@dfan1028 dfan1028 marked this pull request as ready for review July 7, 2026 15:54
@dfan1028 dfan1028 requested a review from a team as a code owner July 7, 2026 15:54
});

it('forwards containerOptions to AstroContainer.create', async () => {
const spy = vi.spyOn(AstroContainer, 'create');

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nit: consider restoring this spy via try/finally or an afterEach cleanup so a failure before mockRestore() does not leave AstroContainer.create mocked for later tests. Not a blocker.

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

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants