CtrlK
BlogDocsLog inGet started
Tessl Logo

tessl/npm-astro

Astro is a modern site builder with web best practices, performance, and DX front-of-mind.

Pending

Quality

Pending

Does it follow best practices?

Impact

Pending

No eval scenarios have been run

SecuritybySnyk

Pending

The risk profile of this skill

Overview
Eval results
Files

container.mddocs/

Container API

The experimental Container API allows rendering Astro components in isolation, useful for testing, server-side rendering, and programmatic component rendering outside of the normal Astro build process.

Capabilities

Create Container

Creates a new container instance for rendering components.

class experimental_AstroContainer {
  /**
   * Creates a new container instance
   */
  static create(
    options?: AstroContainerOptions
  ): Promise<experimental_AstroContainer>;
}

interface AstroContainerOptions {
  streaming?: boolean;
  renderers?: SSRLoadedRenderer[];
  astroConfig?: AstroContainerUserConfig;
  manifest?: SSRManifest;
  resolve?: (specifier: string) => Promise<string>;
}
import { experimental_AstroContainer as AstroContainer } from 'astro/container';
import MyComponent from './MyComponent.astro';

const container = await AstroContainer.create();
const result = await container.renderToString(MyComponent);
console.log(result);

Render To String

Renders a component to an HTML string.

/**
 * Renders a component to HTML string
 */
renderToString(
  component: AstroComponentFactory,
  options?: ContainerRenderOptions
): Promise<string>;

interface ContainerRenderOptions {
  slots?: Record<string, any>;
  request?: Request;
  params?: Record<string, string | undefined>;
  locals?: App.Locals;
  routeType?: 'page' | 'endpoint';
  props?: Props;
  partial?: boolean;
}
import { experimental_AstroContainer as AstroContainer } from 'astro/container';
import Card from './Card.astro';
import Layout from './Layout.astro';

const container = await AstroContainer.create();

// Basic rendering
const html = await container.renderToString(Card, {
  props: { title: 'Hello', content: 'World' },
});

// With slots
const withSlots = await container.renderToString(Layout, {
  slots: {
    default: '<p>Main content</p>',
    sidebar: '<div>Sidebar</div>',
  },
});

// With request context
const withRequest = await container.renderToString(Card, {
  request: new Request('https://example.com/page'),
  params: { slug: 'my-page' },
  locals: { user: { id: '123' } },
});

Render To Response

Renders a component to a Response object.

/**
 * Renders a component to Response object
 */
renderToResponse(
  component: AstroComponentFactory,
  options?: ContainerRenderOptions
): Promise<Response>;
import { experimental_AstroContainer as AstroContainer } from 'astro/container';
import Page from './Page.astro';

const container = await AstroContainer.create();
const response = await container.renderToResponse(Page);

console.log(response.status);
console.log(response.headers.get('content-type'));
const html = await response.text();

Add Server Renderer

Adds a server renderer for framework components (React, Vue, Svelte, etc.).

/**
 * Adds a server renderer to the container
 */
addServerRenderer(options: AddServerRenderer): void;

type AddServerRenderer =
  | {
      renderer: NamedSSRLoadedRendererValue;
    }
  | {
      renderer: SSRLoadedRendererValue;
      name: string;
    };
import { experimental_AstroContainer as AstroContainer } from 'astro/container';
import reactRenderer from '@astrojs/react/server.js';
import vueRenderer from '@astrojs/vue/server.js';
import ReactComponent from './ReactComponent.jsx';

const container = await AstroContainer.create();

container.addServerRenderer({ renderer: reactRenderer });
container.addServerRenderer({ renderer: vueRenderer });

const result = await container.renderToString(ReactComponent);

Add Client Renderer

Adds a client renderer for components with client:* directives.

/**
 * Adds a client renderer for hydration directives
 */
addClientRenderer(options: AddClientRenderer): void;

interface AddClientRenderer {
  name: string;
  entrypoint: string;
}
import { experimental_AstroContainer as AstroContainer } from 'astro/container';
import reactRenderer from '@astrojs/react/server.js';

const container = await AstroContainer.create();

container.addServerRenderer({ renderer: reactRenderer });
container.addClientRenderer({
  name: '@astrojs/react',
  entrypoint: '@astrojs/react/client.js',
});

Insert Page Route

Inserts a page route for Astro.rewrite support.

/**
 * Inserts a page route into the container
 */
insertPageRoute(
  route: string,
  component: AstroComponentFactory,
  params?: Record<string, string | undefined>
): void;
import { experimental_AstroContainer as AstroContainer } from 'astro/container';
import BlogPost from './BlogPost.astro';
import ProductPage from './ProductPage.astro';

const container = await AstroContainer.create();

container.insertPageRoute('/blog/[slug]', BlogPost, { slug: 'my-post' });
container.insertPageRoute('/products/[id]', ProductPage);

const result = await container.renderToString(BlogPost, {
  request: new Request('https://example.com/blog/my-post'),
  params: { slug: 'my-post' },
});

Load Renderers

Utility function for loading renderers.

/**
 * Loads renderers for use in container
 */
function loadRenderers(
  renderers: AstroRenderer[]
): Promise<SSRLoadedRenderer[]>;

interface AstroRenderer {
  name: string;
  serverEntrypoint: string;
  clientEntrypoint?: string;
}

Testing Example

Common pattern for testing Astro components:

import { describe, it, expect } from 'vitest';
import { experimental_AstroContainer as AstroContainer } from 'astro/container';
import MyComponent from '../src/components/MyComponent.astro';

describe('MyComponent', () => {
  it('renders correctly', async () => {
    const container = await AstroContainer.create();
    const result = await container.renderToString(MyComponent, {
      props: {
        title: 'Test Title',
        content: 'Test Content',
      },
    });

    expect(result).toContain('Test Title');
    expect(result).toContain('Test Content');
  });

  it('handles slots', async () => {
    const container = await AstroContainer.create();
    const result = await container.renderToString(MyComponent, {
      slots: {
        default: '<p>Slot content</p>',
      },
    });

    expect(result).toContain('Slot content');
  });
});

SSR Example

Using container for server-side rendering:

import { experimental_AstroContainer as AstroContainer } from 'astro/container';
import Page from './pages/[slug].astro';

export async function handler(request: Request) {
  const url = new URL(request.url);
  const slug = url.pathname.split('/').pop();

  const container = await AstroContainer.create({
    streaming: true,
  });

  const response = await container.renderToResponse(Page, {
    request,
    params: { slug },
    routeType: 'page',
  });

  return response;
}

Types

AstroComponentFactory

interface AstroComponentFactory {
  (result: any, props: any, slots: any): AstroFactoryReturnValue | Promise<AstroFactoryReturnValue>;
  isAstroComponentFactory?: boolean;
  moduleId?: string | undefined;
  propagation?: PropagationHint;
}

type AstroFactoryReturnValue = string | Response;
type PropagationHint = 'none' | 'in-tree' | 'self';

ComponentInstance

interface ComponentInstance {
  default: AstroComponentFactory;
  getStaticPaths?: () => GetStaticPathsResult | Promise<GetStaticPathsResult>;
  css?: string[];
  partial?: boolean;
  prerender?: boolean;
}

AstroContainerUserConfig

/**
 * Subset of Astro configuration for container API
 */
type AstroContainerUserConfig = Omit<AstroUserConfig, 'integrations' | 'adapter'>;
import { experimental_AstroContainer as AstroContainer } from 'astro/container';

const container = await AstroContainer.create({
  astroConfig: {
    site: 'https://example.com',
    base: '/blog',
    trailingSlash: 'always',
    build: {
      format: 'directory'
    }
  }
});

Common Issues

  • Framework components: Must add both server and client renderers to use framework components with hydration directives.
  • Missing routes: Use insertPageRoute() if components use Astro.rewrite() or reference other routes.
  • Streaming: Enable streaming: true for better performance with large components.

docs

assets.md

cli-and-build.md

configuration.md

container.md

content-collections.md

content-loaders.md

dev-toolbar.md

environment.md

i18n.md

index.md

integrations.md

middleware.md

server-actions.md

ssr-and-app.md

transitions.md

tile.json