Version: 1.1.0 (Dual Mode Enabled) Date: February 21, 2026 Status: Ready for Implementation
This guide details the process of migrating the Ash Shaw Makeup Portfolio from its current "Mock Data" architecture to a Headless WordPress backend.
The application now supports Dual Mode:
- Mock Mode (Default): Uses local JSON data for fast development and static hosting.
- WordPress Mode: Uses
useContenthooks to fetch data from a live WordPress API.
Switching Modes:
The mode is controlled entirely by the VITE_USE_WORDPRESS environment variable. No code changes are required to switch backends.
useContent.ts -> Checks VITE_USE_WORDPRESS -> Routes to useMockData.ts OR useWordPress.ts
You will need a fresh WordPress installation (local via LocalWP or hosted).
Install and activate the following plugins:
- ACF (Advanced Custom Fields): For custom metadata.
- CPT UI (Custom Post Type UI): To create the
Portfoliopost type. - WP All Import (Free or Pro): To import the content JSON.
- WP GraphQL (Optional): If you prefer GraphQL over REST (our hooks use REST for simplicity).
- Classic Editor (Optional): If you prefer Markdown-like writing over Gutenberg blocks.
Using CPT UI, register a new post type:
- Slug:
portfolio - Plural Label: Portfolio Entries
- Singular Label: Portfolio Entry
- Supports: Title, Editor, Thumbnail, Excerpt, Custom Fields, Revisions.
- Taxonomies: Create
portfolio_categoryandpost_tag. - REST API: Enable (Show in REST API: True). This is critical.
Create a Field Group named "Portfolio Metadata" and assign it to Post Type = Portfolio. Add the following fields:
- Location (
_location) - Text - Event (
_event) - Text - Featured (
_featured) - True/False - Images (
_images) - Repeater (or JSON Text Area if importing raw JSON).- Note: The export script outputs
_imagesas a JSON string. You can either import it into a Text Area field (simple) or map it to an ACF Repeater (complex). For the prototype, a Text Area field named_imagesis recommended.
- Note: The export script outputs
The export file was previously located at /dist/wordpress-export.json. This file has been deleted (it was a build artifact removed during the Feb 25, 2026 cleanup audit).
To regenerate it, run:
ts-node scripts/export-content.ts
This will recreate wordpress-export.json in /dist/. The /dist/ folder is excluded from source control.
- Go to All Import > New Import.
- Upload
wordpress-export.json(after regenerating it per step 3.1). - Select New Items and choose Post (for blog) or Portfolio Entry (for portfolio).
- Note: You will need to run the import twice: once for Posts and once for Portfolio items, filtering the JSON path if possible, or just letting it skip mismatched types.
- Important: Image Paths: The
featured_imagefield in the JSON export may containfigma:asset/...paths (internal React paths). These will not be automatically imported by WordPress.- Solution A: Upload all images to the WordPress Media Library manually first.
- Solution B: Replace
figma:asset/...paths in the JSON with public URLs before importing. - Solution C: Use a custom PHP script to resolve the asset paths (advanced).
- Drag & Drop Mapping:
- Title:
{post_title} - Content:
{post_content} - Excerpt:
{post_excerpt} - Date:
{post_date} - Slug:
{post_slug} - Featured Image:
{featured_image}(WP All Import can download these URLs).
- Title:
- Custom Fields (ACF):
_location:{meta/_location}_event:{meta/_event}_featured:{meta/_featured}_images:{meta/_images}
- Taxonomies:
- Map
{taxonomies/category}to Categories. - Map
{taxonomies/post_tag}to Tags.
- Map
- Run the import.
To enable WordPress mode, create or update .env:
VITE_USE_WORDPRESS=true
VITE_WP_API_URL=https://your-wordpress-site.com/wp-json/wp/v2To revert to Mock Data, simply set VITE_USE_WORDPRESS=false or remove the line.
Open the browser console in development mode. You should see:
🔌 Content Mode: WordPress API
No code changes are required in components. BlogPage.tsx and PortfolioMainPage.tsx have been updated to use the unified useContent hooks.
- JSON Export file exists and contains data.
- WordPress instance is running with REST API enabled.
-
portfolioCPT is registered and accessible via/wp-json/wp/v2/portfolio. - Content is imported with correct images and metadata.
- React app is fetching data from the API endpoint when
VITE_USE_WORDPRESS=true.
Troubleshooting:
- CORS Error: Install the "WP GraphQL CORS" or similar plugin on WordPress to allow requests from
localhost:5173. - Images not loading: Ensure the imported images are publicly accessible.