Imported from JUVOJustin/astrojs-wp-integration (
AGENTS.md). Install upstream withnpx skills add JUVOJustin/astrojs-wp-integration. Copyright stays with the author.
Agent Instructions
Project Overview
This repository ships one npm package:
wp-astrojs-integration(src/) — Astro loaders, Astro actions, auth bridge, catalog virtual modules, and components built on top of the publishedfluent-wp-clientpackage- The package also exposes
wp-astrojs-integration/integration, an Astro integration that can fetch and cache a WordPress discovery catalog for catalog-aware helpers.
Architecture Priorities
- Treat
WordPressClientfromfluent-wp-clientas the core integration layer. Add or harden client-backed behavior before introducing higher-level loaders, bridges, or actions that depend on it. - Build loaders, actions, and helpers on top of proven published client primitives.
- The package is aligned to
fluent-wp-client^3.0.1; loader payloads for post/page resources must remain plain serializable objects (no legacy helper methods onentry.data). - Keep the package aligned with WordPress' extensibility model. Default to generic resource-oriented patterns that work for core entities, custom post types, custom taxonomies, plugin endpoints, and custom auth flows.
- Prefer Standard Schema-compatible validators for client response validation interfaces so consumers can use Zod or any other compliant schema library.
- Validate and require only the minimum data needed for a feature to work.
- Avoid hard-coding assumptions that only fit default posts/pages.
Astro Actions Imports
- All Astro Actions imports must use the public
astro:actionsvirtual module. Never import from internal paths likeastro/actions/runtime/server.jsorastro/actions/runtime/entrypoints/server.js. The virtual module is resolved fortscvia the type declarations configured insrc/env.d.ts.
Testing
Philosophy
- Integration tests only — no unit tests. Every test runs against a real WordPress instance.
- Tests exercise the full stack: TypeScript code -> HTTP -> WordPress REST API -> response validation.
- Prioritize Astro integration behavior (loader contracts, action schema/auth wiring, and error mapping). Avoid extensive re-validation of low-level REST semantics already covered by
fluent-wp-client.
Test infrastructure
| Component | Purpose |
|---|---|
@wordpress/env |
Spawns a local WordPress Docker container |
Vitest |
Root test runner with projects (integration, static-build) in vitest.config.ts |
.wp-env.json |
wp-env config — PHP version, automatic port selection, mu-plugin mappings, lifecycle scripts |
tests/wp-env/mu-plugins/ |
Must-use plugins mounted into the WP container |
tests/wp-env/seed-content.php |
Idempotent PHP script that generates all test content on startup |
tests/setup/global-setup.ts |
Waits for WP API, creates app password + JWT token, seeds cookie+nonce auth env vars, and boots the shared Astro dev server fixture |
tests/setup/env-loader.ts |
Loads .test-env.json into Vitest workers |
tests/fixtures/astro-site/ |
Shared Astro server fixture that exposes real /_actions/* RPC endpoints for integration tests |
tests/helpers/astro-preview.ts |
Builds the shared fixture with @astrojs/node and runs the standalone server for route-caching coverage |
tests/helpers/ |
Shared test utilities |
Seed data
Test content is generated by tests/wp-env/seed-content.php, which runs automatically on every wp-env start via the afterStart lifecycle script in .wp-env.json.
Contents
| Entity | Count | Details |
|---|---|---|
| Categories | 5 (+1 Uncategorized) | Technology, Science, Travel, Food, Health |
| Tags | 8 | featured, trending, tutorial, review, guide, news, opinion, update |
| Genres (custom taxonomy) | 4 | sci-fi, fantasy, mystery, biography; taxonomy genre, rest_base genres |
| Posts | 150 | test-post-001 – test-post-150 |
| Pages | 10 | About, Contact, Services, FAQ, Team, Blog, Portfolio, Testimonials, Privacy Policy, Terms of Service |
| Books (CPT) | 10 | test-book-001 – test-book-010; registered by tests/wp-env/mu-plugins/register-book-cpt.php, rest_base books |
Native WordPress meta seed data
Native REST meta fields are registered by tests/wp-env/mu-plugins/register-test-meta.php and seeded by tests/wp-env/seed-content.php.
| Entity | Slug | Meta fields set |
|---|---|---|
| Post | test-post-001 |
test_string_meta, test_number_meta, test_array_meta |
| Page | about |
test_string_meta, test_number_meta, test_array_meta |
| Book | test-book-001 |
test_string_meta, test_number_meta, test_array_meta, test_book_isbn |
ACF seed data
ACF fields are registered by tests/wp-env/mu-plugins/register-acf-fields.php with show_in_rest => 1.
| Entity | ACF fields set |
|---|---|
| Posts 001–003 | acf_subtitle, acf_summary, acf_priority_score, acf_external_url, acf_project_status, acf_related_posts, acf_featured_post |
| Pages: about, contact | acf_subtitle, acf_summary, acf_priority_score, acf_external_url, acf_project_status, acf_related_posts |
| Books 001–002 | acf_subtitle, acf_summary, acf_priority_score, acf_project_status, acf_featured_post |
Plugin requirements
- The test environment installs or activates the free ACF plugin during
npm run wp:start. - The test environment also installs
jwt-authentication-for-wp-rest-apiduringnpm run wp:startand setsJWT_AUTH_SECRET_KEYin.wp-env.json. - WordPress ability integration tests rely on the core
wp_register_ability()API when available. Test abilities are registered bytests/wp-env/mu-plugins/register-test-abilities.php.
Running tests
npm run wp:start
npm test # All test projects (integration + static-build)
npm run test:integration # Integration project only (loaders, actions, auth)
npm run test:build # Static build project only
npm run wp:stop
npm run wp:clean
Astro build integration test
tests/integration/loaders/static-loader-build.test.ts runs a real astro build against
the shared fixture project in tests/fixtures/astro-site/.
The fixture defines content collections backed by the package's static loaders
and an Astro page that renders the fetched data. The test sets
ASTRO_TEST_MODE=build so the shared astro.config.mjs switches to static
output for build-only validation. This verifies the full Astro pipeline
(content config, loader execution, page rendering) works end-to-end.
The build test runs through the static-build project in vitest.config.ts.
It loads WP_BASE_URL via tests/setup/env-loader.ts but skips the heavy
integration globalSetup (wp-cli password reset, app-password creation)
because it only needs the public WordPress REST API.
How to write new tests
- Always write integration tests.
- Place Astro-facing integration tests in
tests/integration/. - Use helpers from
tests/helpers/wp-client.ts. - Prefer assertions about Astro-facing behavior and package contracts over exhaustive endpoint semantics.
- Use exact counts and known slugs from the seeded content only when they validate Astro integration behavior.
- Cover success paths and error paths.
- Route action integration tests through the shared Astro dev server fixture (
tests/fixtures/astro-site/) and real/_actions/*RPC endpoints. Do not execute package action helpers directly inside test workers. - Route-caching coverage should build the shared fixture and run the standalone Node adapter entry so Astro cache behavior is exercised in production mode.
Reference suites:
tests/integration/loaders/static-loader-build.test.tstests/integration/loaders/static-loaders.test.tstests/integration/loaders/live-loaders.test.tstests/integration/loaders/live-loader-runtime.test.tstests/integration/loaders/route-caching-runtime.test.tstests/integration/actions/posts.test.tstests/integration/actions/pages.test.tstests/integration/actions/users.test.tstests/integration/actions/books.test.tstests/integration/actions/terms.test.tstests/integration/actions/meta.test.tstests/integration/actions/acf.test.tstests/integration/actions/abilities.test.tstests/integration/actions/auth-bridge.test.ts
Key gotchas
wp-envoutput includes status lines (ℹ/✔). ThewpCli()helper intests/setup/global-setup.tsstrips them.- Vitest
globalSetupruns in a separate process, so env vars are bridged through.test-env.json. - WordPress application passwords require HTTPS by default;
tests/wp-env/mu-plugins/enable-app-passwords.phpoverrides this for HTTP localhost. - JWT auth relies on
tests/wp-env/mu-plugins/enable-jwt-auth-header.phpsoAuthorizationheaders survive local wp-env rewrites. - The WP REST API caps
per_pageat 100. - Astro route caching is disabled in
astro dev; cache behavior must be validated against the standalone server build used bytests/helpers/astro-preview.ts.
Code Style
- After making code changes, run
npm run format:checkand ensure Biome reports no formatting issues before finalizing. - Astro loaders are split into
src/loaders/static.tsandsrc/loaders/live.ts. - Shared runtime helpers for Astro middleware, actions, and auth flows should prefer web-standard APIs so they work on Node and non-Node adapters.
- All public API is re-exported from
src/index.ts. - AI SDK helpers are owned by
fluent-wp-client/ai-sdk; this package should not add live-loader-backed AI wrappers because live loaders do not receive Astro request auth context. - New discovery features (CLI, runtime schema conversion, embed extraction helpers) are re-exported from
fluent-wp-clientandfluent-wp-client/zodsubpackages. - Actions and loaders use the v3 client API:
client.content('posts').list()instead ofclient.getPosts(),client.users().me()instead ofclient.getCurrentUser().
npm Package
wp-astrojs-integration publishes dist/ and src/components/.
The repository consumes fluent-wp-client from npm, so local package mirrors should not be reintroduced.
When package structure changes, verify published contents with npm pack --dry-run.