Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
59 commits
Select commit Hold shift + click to select a range
85b5f9a
Initial commit to test site-spec app integration
aagam-shah Aug 26, 2025
f6c42b1
Save state
ariskataoka Sep 1, 2025
54697b3
Import site-spec as we do for other wpcom scripts
ariskataoka Sep 1, 2025
a119705
Cleanup
ariskataoka Sep 1, 2025
01bc241
More cleanup
ariskataoka Sep 2, 2025
bc126ec
Try move loading css
ariskataoka Sep 2, 2025
e9a9f24
Move css load to a more appropriate area
ariskataoka Sep 3, 2025
8d0f4a6
Move css to its own function
ariskataoka Sep 3, 2025
879e62a
Cleanup
ariskataoka Sep 3, 2025
ce1a4cf
We dont need react imports as it is now part of the SiteSpec bundle
ariskataoka Sep 3, 2025
8bad13c
Cleanup
ariskataoka Sep 3, 2025
60cf575
Linter
ariskataoka Sep 3, 2025
7cd03a5
Rename site-spec-script with site-spec
ariskataoka Sep 3, 2025
0cede20
Add css url config
ariskataoka Sep 3, 2025
af6a7d4
Group site-spec config into its own section
ariskataoka Sep 3, 2025
d71f7a0
Add note to readme
ariskataoka Sep 3, 2025
8547d78
Remove complexity
ariskataoka Sep 3, 2025
47bc6d9
Linter
ariskataoka Sep 3, 2025
889c6a1
Update readme with load css details
ariskataoka Sep 3, 2025
0f39f97
FIx test
ariskataoka Sep 3, 2025
67d92e5
Add correct URLs for site-spec script and css
ariskataoka Sep 3, 2025
4e1f882
Remove debug logs
ariskataoka Sep 3, 2025
2f84961
Merge remote-tracking branch 'origin/trunk' into try/site-spec-integr…
ariskataoka Sep 4, 2025
c3b58f7
Refactor get config css and url
ariskataoka Sep 4, 2025
ccf659a
Convert js to ts
ariskataoka Sep 4, 2025
15bbe3b
Merge remote-tracking branch 'origin/trunk' into try/site-spec-integr…
ariskataoka Sep 5, 2025
4882049
Remove configs that contains default
ariskataoka Sep 5, 2025
9c3cc2f
Tidy up
ariskataoka Sep 5, 2025
cba372d
Update tests
ariskataoka Sep 5, 2025
374fd34
Load dynamically not for all the pages
ariskataoka Sep 5, 2025
3eb53ac
Update readme and remove logs
ariskataoka Sep 5, 2025
e152f0b
Remove unnecessary code
ariskataoka Sep 5, 2025
c919ad9
Remove duplicated configs as Calypso use same site-spec configs for a…
ariskataoka Sep 5, 2025
bee1f1d
Adjust jsdocs and readme
ariskataoka Sep 5, 2025
5d57550
Remove console.logs
ariskataoka Sep 5, 2025
94d0613
Merge remote-tracking branch 'origin/trunk' into try/site-spec-integr…
ariskataoka Sep 5, 2025
980d3ad
Fix readme codestyle
ariskataoka Sep 5, 2025
51f6fa9
Fix tests
ariskataoka Sep 5, 2025
532bd7e
Rename learning step to site spec
ariskataoka Sep 5, 2025
0f5a61c
Refactor initialize
ariskataoka Sep 5, 2025
777496b
Update slug
ariskataoka Sep 8, 2025
7ee4c12
Return all steps rather than only site-spec for requests without spec_id
ariskataoka Sep 8, 2025
d7134af
Merge remote-tracking branch 'origin/trunk' into try/site-spec-integr…
ariskataoka Sep 8, 2025
5061404
Fix array branch error
ariskataoka Sep 8, 2025
d6f7b36
Update site-spec bundle version
ariskataoka Sep 8, 2025
213ebd9
Throw err instead of reject
ariskataoka Sep 9, 2025
d10e817
Warn when site-spec fails to load
ariskataoka Sep 9, 2025
bd05489
Verify blank space in config url as well
ariskataoka Sep 9, 2025
3187eb9
Fix test mock complexity
ariskataoka Sep 9, 2025
f2cb5ad
Merge remote-tracking branch 'origin/trunk' into try/site-spec-integr…
ariskataoka Sep 9, 2025
424006d
Merge remote-tracking branch 'origin/trunk' into try/site-spec-integr…
ariskataoka Sep 9, 2025
d51a605
Merge remote-tracking branch 'origin/trunk' into try/site-spec-integr…
ariskataoka Sep 12, 2025
e9126d2
Keep default behaviour when site-spec is set to false
ariskataoka Sep 12, 2025
9e9bfcc
Enable site-spec in stage config
ariskataoka Sep 12, 2025
3c216b4
Remove mem limit from start project
ariskataoka Sep 12, 2025
8afd948
Merge remote-tracking branch 'origin/trunk' into try/site-spec-integr…
ariskataoka Sep 12, 2025
e7d333c
Merge branch 'trunk' into try/site-spec-integration-cdn
aagam-shah Sep 16, 2025
971108a
Add route for site-spec integration flow (#105761)
ariskataoka Sep 16, 2025
fb1ebd0
Merge branch 'trunk' into try/site-spec-integration-cdn
aagam-shah Sep 16, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
import config from '@automattic/calypso-config';
import { AI_SITE_BUILDER_SPEC_FLOW, ONBOARDING_FLOW } from '@automattic/onboarding';
import { STEPS } from '../../internals/steps';
import { FlowV2 } from '../../internals/types';

function initialize() {
// Check if site-spec feature flag is enabled
if ( ! config.isEnabled( 'site-spec' ) ) {
// Redirect to default flow (same as Calypso's 404 behavior)
window.location.href = `/setup/${ ONBOARDING_FLOW }${ window.location.search }`;
return [];
}

// Check for spec_id parameter - if present, redirect to main ai-site-builder flow
const queryParams = new URLSearchParams( window.location.search );
const specId = queryParams.get( 'spec_id' );

if ( specId ) {
// Redirect to main ai-site-builder flow with spec_id
window.location.replace( `/setup/ai-site-builder?spec_id=${ specId }` );
return [];
}

// Only show the site-spec step (with empty slug for clean URL)
return [ STEPS.SITE_SPEC ];
}

const aiSiteBuilderSpec: FlowV2< typeof initialize > = {
name: AI_SITE_BUILDER_SPEC_FLOW,
isSignupFlow: true,
__experimentalUseBuiltinAuth: true,
initialize,
useStepNavigation: () => {
return { submit: () => {} };
},
};

export default aiSiteBuilderSpec;
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
import { useTranslate } from 'i18n-calypso';
import DocumentHead from 'calypso/components/data/document-head';
import { useSiteSpec } from 'calypso/lib/site-spec';
import type { Step as StepType } from '../../types';

const SiteSpec: StepType = function SiteSpec() {
const translate = useTranslate();
// Use the SiteSpec hook to handle the loading and initialization of the SiteSpec widget
useSiteSpec();

return (
<>
<DocumentHead title={ translate( 'Build Your Site with AI' ) } />
<div id="site-spec-container" />
</>
);
};

export default SiteSpec;
5 changes: 5 additions & 0 deletions client/landing/stepper/declarative-flow/internals/steps.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -167,6 +167,11 @@ export const STEPS = {
asyncComponent: () => import( './steps-repository/launch-big-sky' ),
},

SITE_SPEC: {
slug: 'site-spec',
asyncComponent: () => import( './steps-repository/site-spec' ),
},

LAUNCHPAD: { slug: 'launchpad', asyncComponent: () => import( './steps-repository/launchpad' ) },

OPTIONS: {
Expand Down
6 changes: 6 additions & 0 deletions client/landing/stepper/declarative-flow/registered-flows.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ import {
HUNDRED_YEAR_DOMAIN_FLOW,
EXAMPLE_FLOW,
AI_SITE_BUILDER_FLOW,
AI_SITE_BUILDER_SPEC_FLOW,
ONBOARDING_UNIFIED_FLOW,
} from '@automattic/onboarding';
import type { Flow, FlowV2 } from '../declarative-flow/internals/types';
Expand Down Expand Up @@ -42,6 +43,11 @@ const availableFlows: Record< string, () => Promise< { default: FlowV2< any > }
),

[ DOMAIN_FLOW ]: () => import( /* webpackChunkName: "domain-flow" */ './flows/domain/domain' ),

[ AI_SITE_BUILDER_SPEC_FLOW ]: () =>
import(
/* webpackChunkName: "ai-site-builder-spec-flow" */ './flows/ai-site-builder-spec/ai-site-builder-spec'
),
};

/**
Expand Down
148 changes: 148 additions & 0 deletions client/lib/site-spec/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,148 @@
# Site-Spec Integration Library

A React hook for integrating the SiteSpec AI site builder widget into WordPress Calypso components.

## Overview

This library provides a reusable React hook that handles loading and initializing the SiteSpec widget. It manages script loading, DOM manipulation, and cleanup.

## Features

- **Automatic Loading**: Loads CSS and JavaScript resources only when needed
- **React Integration**: hook-based API for React components
- **Auto Cleanup**: Cleans up resources when components unmount

## Configuration

### Feature Flag

Enable the SiteSpec integration with the `site-spec` feature flag:

```json
{
"features": {
"site-spec": true
}
}
```

### Configuration Keys

Define the following configuration values:

- `site_spec.script_url`: Base URL for the Site-Spec JavaScript bundle
- `site_spec.css_url`: URL for the Site-Spec CSS styles
- `site_spec.agent_id`: Identifier for the Site-Spec agent
- `site_spec.agent_url`: (Optional) API endpoint for the Site-Spec agent
- `site_spec.build_site_url`: (Optional) URL template for building sites

**Note:** `agent_url` and `build_site_url` are optional. If not provided, the Site-Spec library will use its own defaults.

### Environment-Specific Configuration

#### Development

```json
{
"site_spec": {
"script_url": "http://widgets.wp.com/site-spec/bundle-1.0.0.umd.js",
"css_url": "http://widgets.wp.com/site-spec/style-1.0.0.css",
"agent_id": "site-spec"
},
"features": {
"site-spec": true
}
}
```

**Note:** We are using `bundle-1.0.0.umd.js` because React is not available globally in the version required by SiteSpec. The bundled version includes its own React instance to avoid version conflicts with WordPress Calypso's React setup.

#### Production

```json
{
"site_spec": {
"script_url": "https://widgets.wp.com/site-spec/bundle-1.0.0.umd.js",
"css_url": "https://widgets.wp.com/site-spec/style-1.0.0.css",
"agent_id": "site-spec"
},
"features": {
"site-spec": true
}
}
```

## Usage

### Basic Usage

```typescript
import { useSiteSpec } from 'calypso/lib/site-spec';

const MyComponent = () => {
useSiteSpec({ container: '#site-spec-container' });
return <div id="site-spec-container" />;
};
```

### With Event Handlers

```typescript
import { useSiteSpec } from 'calypso/lib/site-spec';

const SiteSpecComponent = () => {
useSiteSpec({
container: '#site-spec-container',
onMessage: (message) => {
console.log('SiteSpec message:', message);
},
onError: (error) => {
console.error('SiteSpec error:', error);
},
});

return <div id="site-spec-container" />;
};

export default SiteSpecComponent;
```

## API Reference

### `useSiteSpec(options)`

Custom React hook for loading and managing SiteSpec resources.

#### Parameters

- `options.container` (string | HTMLElement, optional): Container selector or DOM element for the widget (default: `'#site-spec-container'`)
- `options.onMessage` (function, optional): Message handler callback for SiteSpec widget messages
- `options.onError` (function, optional): Error handler callback for loading and initialization errors

#### Example

```typescript
useSiteSpec({
container: '#my-site-spec-container',
onMessage: (message) => {
console.log('Received message:', message);
},
onError: (error) => {
console.error('SiteSpec error:', error);
},
});
```

## How It Works

1. **Feature Check**: Verifies that the `site-spec` feature flag is enabled
2. **SSR Guard**: Exits early if running in server-side rendering or non-browser environment
3. **Resource Loading**: Dynamically loads CSS and JavaScript from the configured URLs (with duplicate request prevention)
4. **Widget Initialization**: Initializes the SiteSpec widget with the provided configuration
5. **Cleanup**: Removes internal state and tracking when the component unmounts

## Notes

- The hook automatically handles duplicate initialization attempts and prevents multiple initializations of the same container
- Resources are only loaded when the component mounts and the feature flag is enabled
- Internal state is cleaned up when the component unmounts, but loaded resources remain in the DOM for reuse
1 change: 1 addition & 0 deletions client/lib/site-spec/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export { useSiteSpec } from './use-site-spec';
Loading