create-content-sdk-app 2.0.2 → 2.1.0-canary.10
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE.MD +202 -202
- package/dist/templates/nextjs/.agents/skills/content-sdk-component-data-strategy/SKILL.md +1 -1
- package/dist/templates/nextjs/.agents/skills/content-sdk-component-registration/SKILL.md +1 -1
- package/dist/templates/nextjs/.agents/skills/content-sdk-component-scaffold/SKILL.md +1 -1
- package/dist/templates/nextjs/.agents/skills/content-sdk-component-variants/SKILL.md +1 -1
- package/dist/templates/nextjs/.agents/skills/content-sdk-dictionary-and-i18n/SKILL.md +1 -1
- package/dist/templates/nextjs/.agents/skills/content-sdk-editing-safe-rendering/SKILL.md +1 -1
- package/dist/templates/nextjs/.agents/skills/content-sdk-field-usage-image-link-text/SKILL.md +1 -1
- package/dist/templates/nextjs/.agents/skills/content-sdk-graphql-data-fetching/SKILL.md +1 -1
- package/dist/templates/nextjs/.agents/skills/content-sdk-multisite-management/SKILL.md +1 -1
- package/dist/templates/nextjs/.agents/skills/content-sdk-route-configuration/SKILL.md +1 -1
- package/dist/templates/nextjs/.agents/skills/content-sdk-site-setup-and-env/SKILL.md +1 -1
- package/dist/templates/nextjs/.agents/skills/content-sdk-sitemap-robots/SKILL.md +1 -1
- package/dist/templates/nextjs/.agents/skills/content-sdk-troubleshoot-editing/SKILL.md +1 -1
- package/dist/templates/nextjs/.agents/skills/content-sdk-upgrade-assistant/SKILL.md +1 -1
- package/dist/templates/nextjs/.cursor/rules/general.mdc +81 -81
- package/dist/templates/nextjs/.cursor/rules/javascript.mdc +112 -112
- package/dist/templates/nextjs/.cursor/rules/project-setup.mdc +100 -100
- package/dist/templates/nextjs/.cursor/rules/sitecore.mdc +150 -150
- package/dist/templates/nextjs/.env.container.example +27 -27
- package/dist/templates/nextjs/.env.remote.example +51 -51
- package/dist/templates/nextjs/.gitattributes +11 -11
- package/dist/templates/nextjs/.prettierrc +8 -8
- package/dist/templates/nextjs/.vscode/extensions.json +8 -8
- package/dist/templates/nextjs/.vscode/launch.json +15 -15
- package/dist/templates/nextjs/.windsurfrules +186 -186
- package/dist/templates/nextjs/AGENTS.md +1 -1
- package/dist/templates/nextjs/LICENSE.txt +202 -202
- package/dist/templates/nextjs/README.md +1 -5
- package/dist/templates/nextjs/Skills.md +2 -2
- package/dist/templates/nextjs/eslint.config.mjs +81 -81
- package/dist/templates/nextjs/gitignore +28 -28
- package/dist/templates/nextjs/package.json +68 -68
- package/dist/templates/nextjs/sitecore.config.ts.example +40 -40
- package/dist/templates/nextjs/src/proxy.ts +11 -3
- package/dist/templates/nextjs/tsconfig.json +40 -40
- package/dist/templates/nextjs-app-router/.agents/skills/content-sdk-component-data-strategy/SKILL.md +1 -1
- package/dist/templates/nextjs-app-router/.agents/skills/content-sdk-component-registration/SKILL.md +1 -1
- package/dist/templates/nextjs-app-router/.agents/skills/content-sdk-component-scaffold/SKILL.md +1 -1
- package/dist/templates/nextjs-app-router/.agents/skills/content-sdk-component-variants/SKILL.md +1 -1
- package/dist/templates/nextjs-app-router/.agents/skills/content-sdk-dictionary-and-i18n/SKILL.md +1 -1
- package/dist/templates/nextjs-app-router/.agents/skills/content-sdk-editing-safe-rendering/SKILL.md +1 -1
- package/dist/templates/nextjs-app-router/.agents/skills/content-sdk-field-usage-image-link-text/SKILL.md +1 -1
- package/dist/templates/nextjs-app-router/.agents/skills/content-sdk-graphql-data-fetching/SKILL.md +1 -1
- package/dist/templates/nextjs-app-router/.agents/skills/content-sdk-multisite-management/SKILL.md +1 -1
- package/dist/templates/nextjs-app-router/.agents/skills/content-sdk-route-configuration/SKILL.md +1 -1
- package/dist/templates/nextjs-app-router/.agents/skills/content-sdk-site-setup-and-env/SKILL.md +1 -1
- package/dist/templates/nextjs-app-router/.agents/skills/content-sdk-sitemap-robots/SKILL.md +1 -1
- package/dist/templates/nextjs-app-router/.agents/skills/content-sdk-troubleshoot-editing/SKILL.md +1 -1
- package/dist/templates/nextjs-app-router/.agents/skills/content-sdk-upgrade-assistant/SKILL.md +1 -1
- package/dist/templates/nextjs-app-router/.cursor/rules/app-router-setup.mdc +116 -116
- package/dist/templates/nextjs-app-router/.cursor/rules/general.mdc +80 -80
- package/dist/templates/nextjs-app-router/.cursor/rules/javascript.mdc +112 -112
- package/dist/templates/nextjs-app-router/.cursor/rules/sitecore.mdc +174 -174
- package/dist/templates/nextjs-app-router/.env.container.example +27 -27
- package/dist/templates/nextjs-app-router/.env.remote.example +51 -51
- package/dist/templates/nextjs-app-router/.gitattributes +11 -11
- package/dist/templates/nextjs-app-router/.windsurfrules +290 -290
- package/dist/templates/nextjs-app-router/AGENTS.md +1 -1
- package/dist/templates/nextjs-app-router/README.md +1 -5
- package/dist/templates/nextjs-app-router/Skills.md +2 -2
- package/dist/templates/nextjs-app-router/eslint.config.mjs +21 -29
- package/dist/templates/nextjs-app-router/gitignore +31 -31
- package/dist/templates/nextjs-app-router/package.json +54 -55
- package/dist/templates/nextjs-app-router/postcss.config.mjs +5 -5
- package/dist/templates/nextjs-app-router/sitecore.config.ts.example +40 -40
- package/dist/templates/nextjs-app-router/src/app/globals.css +1 -1
- package/dist/templates/nextjs-app-router/src/proxy.ts +11 -3
- package/dist/templates/nextjs-app-router/tsconfig.json +48 -48
- package/package.json +2 -2
|
@@ -1,290 +1,290 @@
|
|
|
1
|
-
# Sitecore Content SDK Next.js App Router Project - Windsurf AI Rules
|
|
2
|
-
|
|
3
|
-
## Project Purpose and Tech Stack
|
|
4
|
-
|
|
5
|
-
This is a **Sitecore Content SDK** application built with **Next.js App Router** and **TypeScript**. The project follows Sitecore best practices for XM Cloud development and leverages the latest Next.js App Router features for improved performance and developer experience.
|
|
6
|
-
|
|
7
|
-
### Key Technologies
|
|
8
|
-
|
|
9
|
-
- **Next.js App Router** - React framework with Server Components and modern routing
|
|
10
|
-
- **Sitecore Content SDK** - Official SDK for Sitecore XM Cloud integration
|
|
11
|
-
- **TypeScript** - Type-safe JavaScript development
|
|
12
|
-
- **Sitecore XM Cloud** - Headless CMS platform
|
|
13
|
-
- **React Server Components** - Server-side rendering for better performance
|
|
14
|
-
- **next-intl** - Internationalization support
|
|
15
|
-
|
|
16
|
-
## Coding Standards
|
|
17
|
-
|
|
18
|
-
### TypeScript Standards
|
|
19
|
-
|
|
20
|
-
- Use **strict mode** in tsconfig.json
|
|
21
|
-
- Prefer type assertions over `any`: `value as ContentItem`
|
|
22
|
-
- Use discriminated unions for complex state management
|
|
23
|
-
- Enable strict null checks and strict function types
|
|
24
|
-
|
|
25
|
-
### Naming Conventions
|
|
26
|
-
|
|
27
|
-
- **Variables/Functions**: camelCase (`getUserData()`, `isLoading`, `currentUser`)
|
|
28
|
-
- **Components**: PascalCase (`SitecoreComponent`, `PageLayout`, `ContentBlock`)
|
|
29
|
-
- **Constants**: UPPER_SNAKE_CASE (`API_ENDPOINT`, `DEFAULT_TIMEOUT`)
|
|
30
|
-
- **Directories**: kebab-case (`src/components`, `src/api-clients`)
|
|
31
|
-
- **Types/Interfaces**: PascalCase (`ContentItem`, `LayoutProps`, `SitecoreConfig`)
|
|
32
|
-
|
|
33
|
-
### Modular Layout (App Router)
|
|
34
|
-
|
|
35
|
-
```
|
|
36
|
-
src/
|
|
37
|
-
app/ # App Router pages and layouts
|
|
38
|
-
components/ # UI components (React)
|
|
39
|
-
lib/ # Configuration and utilities
|
|
40
|
-
i18n/ # Internationalization setup
|
|
41
|
-
types/ # TypeScript type definitions
|
|
42
|
-
hooks/ # Custom React hooks
|
|
43
|
-
```
|
|
44
|
-
|
|
45
|
-
## Library Usage
|
|
46
|
-
|
|
47
|
-
### @sitecore-content-sdk
|
|
48
|
-
|
|
49
|
-
- Use `SitecoreClient` for content fetching
|
|
50
|
-
- Implement proper error handling with try/catch blocks
|
|
51
|
-
- Cache API responses using React Query or SWR
|
|
52
|
-
- Handle content preview vs. published content scenarios
|
|
53
|
-
|
|
54
|
-
```typescript
|
|
55
|
-
import { SitecoreClient } from '@sitecore-content-sdk/nextjs/client';
|
|
56
|
-
import scConfig from 'sitecore.config';
|
|
57
|
-
|
|
58
|
-
const client = new SitecoreClient({
|
|
59
|
-
...scConfig,
|
|
60
|
-
});
|
|
61
|
-
```
|
|
62
|
-
|
|
63
|
-
### React App Router Patterns
|
|
64
|
-
|
|
65
|
-
- Use **Server Components** for data fetching and static content (default)
|
|
66
|
-
- Use **Client Components** for interactivity (use 'use client' directive)
|
|
67
|
-
- Implement proper error boundaries with error.tsx
|
|
68
|
-
- Use loading.tsx for loading states
|
|
69
|
-
- Leverage layout.tsx for shared page structure
|
|
70
|
-
|
|
71
|
-
### Sitecore Field Components
|
|
72
|
-
|
|
73
|
-
- Always use Sitecore field components: `<Text>`, `<RichText>`, `<Image>`
|
|
74
|
-
- Validate field existence before rendering
|
|
75
|
-
- Handle empty/null fields gracefully
|
|
76
|
-
- Prefer Sitecore field components over manual rendering
|
|
77
|
-
|
|
78
|
-
```typescript
|
|
79
|
-
// Good: Using Sitecore field components
|
|
80
|
-
<Text field={fields?.title} tag="h1" />
|
|
81
|
-
<RichText field={fields?.content} />
|
|
82
|
-
<Image field={fields?.backgroundImage} />
|
|
83
|
-
|
|
84
|
-
// Avoid: Manual field value extraction unless necessary
|
|
85
|
-
```
|
|
86
|
-
|
|
87
|
-
## Example Patterns and Prompts
|
|
88
|
-
|
|
89
|
-
### Server Component Development
|
|
90
|
-
|
|
91
|
-
```typescript
|
|
92
|
-
// Server Component example (default in App Router)
|
|
93
|
-
import { SitecoreClient } from '@sitecore-content-sdk/nextjs/client';
|
|
94
|
-
import scConfig from 'sitecore.config';
|
|
95
|
-
|
|
96
|
-
const client = new SitecoreClient({
|
|
97
|
-
...scConfig,
|
|
98
|
-
});
|
|
99
|
-
|
|
100
|
-
export default async function SitecorePage({ params }: { params: { path: string[] } }) {
|
|
101
|
-
try {
|
|
102
|
-
const pageData = await client.getPage(params.path.join('/'));
|
|
103
|
-
return <SitecoreLayout layoutData={pageData?.layout} />;
|
|
104
|
-
} catch (error) {
|
|
105
|
-
return <div>Content not found</div>;
|
|
106
|
-
}
|
|
107
|
-
}
|
|
108
|
-
```
|
|
109
|
-
|
|
110
|
-
### Client Component Integration
|
|
111
|
-
|
|
112
|
-
Interactive Sitecore Components:
|
|
113
|
-
|
|
114
|
-
- Use 'use client' directive when needed
|
|
115
|
-
- Keep client components focused on interactivity
|
|
116
|
-
- Pass server-fetched data as props
|
|
117
|
-
- Handle hydration mismatches carefully
|
|
118
|
-
|
|
119
|
-
```typescript
|
|
120
|
-
'use client';
|
|
121
|
-
|
|
122
|
-
interface InteractiveSitecoreComponentProps {
|
|
123
|
-
fields: {
|
|
124
|
-
title: Field;
|
|
125
|
-
content: Field;
|
|
126
|
-
};
|
|
127
|
-
}
|
|
128
|
-
|
|
129
|
-
export default function InteractiveSitecoreComponent({
|
|
130
|
-
fields,
|
|
131
|
-
}: InteractiveSitecoreComponentProps) {
|
|
132
|
-
// Client-side interactivity here
|
|
133
|
-
return (
|
|
134
|
-
<div>
|
|
135
|
-
<Text field={fields?.title} tag="h2" />
|
|
136
|
-
<RichText field={fields?.content} />
|
|
137
|
-
</div>
|
|
138
|
-
);
|
|
139
|
-
}
|
|
140
|
-
```
|
|
141
|
-
|
|
142
|
-
### Component Development
|
|
143
|
-
|
|
144
|
-
```typescript
|
|
145
|
-
// Component props interface
|
|
146
|
-
interface HeroProps {
|
|
147
|
-
fields: {
|
|
148
|
-
title: Field;
|
|
149
|
-
subtitle: Field;
|
|
150
|
-
backgroundImage: Field;
|
|
151
|
-
};
|
|
152
|
-
}
|
|
153
|
-
|
|
154
|
-
export default function Hero({ fields }: HeroProps) {
|
|
155
|
-
return (
|
|
156
|
-
<div>
|
|
157
|
-
<Text field={fields?.title} tag="h1" />
|
|
158
|
-
<Text field={fields?.subtitle} tag="p" />
|
|
159
|
-
<Image field={fields?.backgroundImage} />
|
|
160
|
-
</div>
|
|
161
|
-
);
|
|
162
|
-
}
|
|
163
|
-
```
|
|
164
|
-
|
|
165
|
-
### Error Handling
|
|
166
|
-
|
|
167
|
-
API Calls:
|
|
168
|
-
|
|
169
|
-
- Always wrap in try/catch blocks
|
|
170
|
-
- Throw custom errors with context: `SitecoreFetchError`, `ConfigurationError`
|
|
171
|
-
- Handle edge cases with guard clauses
|
|
172
|
-
|
|
173
|
-
```typescript
|
|
174
|
-
async function fetchPageData(path: string): Promise<Page | null> {
|
|
175
|
-
if (!path) {
|
|
176
|
-
throw new Error('Page path is required');
|
|
177
|
-
}
|
|
178
|
-
|
|
179
|
-
try {
|
|
180
|
-
const pageData = await client.getPage(path);
|
|
181
|
-
return pageData;
|
|
182
|
-
} catch (error) {
|
|
183
|
-
throw new SitecoreFetchError(`Failed to fetch page data for ${path}`, error);
|
|
184
|
-
}
|
|
185
|
-
}
|
|
186
|
-
```
|
|
187
|
-
|
|
188
|
-
### Configuration
|
|
189
|
-
|
|
190
|
-
```typescript
|
|
191
|
-
// sitecore.config.ts
|
|
192
|
-
import { defineConfig } from '@sitecore-content-sdk/nextjs/config';
|
|
193
|
-
|
|
194
|
-
export default defineConfig({
|
|
195
|
-
api: {
|
|
196
|
-
edge: {
|
|
197
|
-
contextId: process.env.SITECORE_EDGE_CONTEXT_ID || '',
|
|
198
|
-
clientContextId: process.env.NEXT_PUBLIC_SITECORE_EDGE_CONTEXT_ID,
|
|
199
|
-
edgeUrl:
|
|
200
|
-
process.env.NEXT_PUBLIC_SITECORE_EDGE_PLATFORM_HOSTNAME ||
|
|
201
|
-
process.env.SITECORE_EDGE_PLATFORM_HOSTNAME ||
|
|
202
|
-
'https://edge-platform.sitecorecloud.io',
|
|
203
|
-
},
|
|
204
|
-
local: {
|
|
205
|
-
apiKey: process.env.SITECORE_API_KEY || '',
|
|
206
|
-
apiHost: process.env.SITECORE_API_HOST || '',
|
|
207
|
-
},
|
|
208
|
-
},
|
|
209
|
-
defaultSite: process.env.NEXT_PUBLIC_DEFAULT_SITE_NAME || 'default',
|
|
210
|
-
defaultLanguage: process.env.NEXT_PUBLIC_DEFAULT_LANGUAGE || 'en',
|
|
211
|
-
editingSecret: process.env.SITECORE_EDITING_SECRET,
|
|
212
|
-
});
|
|
213
|
-
```
|
|
214
|
-
|
|
215
|
-
### Internationalization
|
|
216
|
-
|
|
217
|
-
Multi-language Support:
|
|
218
|
-
|
|
219
|
-
- Configure next-intl for language routing
|
|
220
|
-
- Handle Sitecore language contexts
|
|
221
|
-
- Implement language switching
|
|
222
|
-
- Use proper locale-based data fetching
|
|
223
|
-
|
|
224
|
-
```typescript
|
|
225
|
-
// Language-aware data fetching
|
|
226
|
-
import { getTranslations } from 'next-intl/server';
|
|
227
|
-
|
|
228
|
-
export default async function LocalizedPage() {
|
|
229
|
-
const t = await getTranslations('common');
|
|
230
|
-
// Fetch Sitecore content for current locale
|
|
231
|
-
}
|
|
232
|
-
```
|
|
233
|
-
|
|
234
|
-
## Development Workflow
|
|
235
|
-
|
|
236
|
-
1. **Install dependencies**: `npm install`
|
|
237
|
-
2. **Configure environment**: Copy `.env.example` to `.env.local`
|
|
238
|
-
3. **Start development**: `npm run dev`
|
|
239
|
-
4. **Build for production**: `npm run build`
|
|
240
|
-
|
|
241
|
-
## App Router Best Practices
|
|
242
|
-
|
|
243
|
-
### Server vs Client Components
|
|
244
|
-
|
|
245
|
-
- Use Server Components for Sitecore content rendering (default)
|
|
246
|
-
- Use Client Components for user interactions
|
|
247
|
-
- Minimize client-side JavaScript
|
|
248
|
-
- Leverage server-side data fetching
|
|
249
|
-
|
|
250
|
-
### Routing and Layouts
|
|
251
|
-
|
|
252
|
-
- Use layout.tsx for shared page structure
|
|
253
|
-
- Implement loading.tsx for loading states
|
|
254
|
-
- Create error.tsx for error boundaries
|
|
255
|
-
- Use page.tsx for route content
|
|
256
|
-
- Use [...path] for Sitecore catch-all routes
|
|
257
|
-
|
|
258
|
-
### Performance Optimization
|
|
259
|
-
|
|
260
|
-
- Leverage Server Components for better performance
|
|
261
|
-
- Use streaming for improved loading experience
|
|
262
|
-
- Implement proper caching strategies
|
|
263
|
-
- Optimize images with Next.js Image component
|
|
264
|
-
|
|
265
|
-
## Best Practices
|
|
266
|
-
|
|
267
|
-
### Performance
|
|
268
|
-
|
|
269
|
-
- Optimize images using Next.js Image component
|
|
270
|
-
- Implement proper loading states
|
|
271
|
-
- Cache expensive operations appropriately
|
|
272
|
-
- Consider server-side rendering implications
|
|
273
|
-
- Lazy-load non-critical modules
|
|
274
|
-
- Use Server Components for better performance
|
|
275
|
-
|
|
276
|
-
### Security
|
|
277
|
-
|
|
278
|
-
- Sanitize user inputs before processing
|
|
279
|
-
- Validate data at application boundaries
|
|
280
|
-
- Use HTTPS for all Sitecore connections
|
|
281
|
-
- Never expose sensitive configuration in client-side code
|
|
282
|
-
- Escape content when rendering to prevent XSS
|
|
283
|
-
|
|
284
|
-
### Code Quality
|
|
285
|
-
|
|
286
|
-
- Follow DRY principle - extract common functionality
|
|
287
|
-
- Use SOLID principles for maintainable code
|
|
288
|
-
- Write self-documenting code with clear intent
|
|
289
|
-
- Implement proper error boundaries
|
|
290
|
-
- Test behavior, not implementation details
|
|
1
|
+
# Sitecore Content SDK Next.js App Router Project - Windsurf AI Rules
|
|
2
|
+
|
|
3
|
+
## Project Purpose and Tech Stack
|
|
4
|
+
|
|
5
|
+
This is a **Sitecore Content SDK** application built with **Next.js App Router** and **TypeScript**. The project follows Sitecore best practices for XM Cloud development and leverages the latest Next.js App Router features for improved performance and developer experience.
|
|
6
|
+
|
|
7
|
+
### Key Technologies
|
|
8
|
+
|
|
9
|
+
- **Next.js App Router** - React framework with Server Components and modern routing
|
|
10
|
+
- **Sitecore Content SDK** - Official SDK for Sitecore XM Cloud integration
|
|
11
|
+
- **TypeScript** - Type-safe JavaScript development
|
|
12
|
+
- **Sitecore XM Cloud** - Headless CMS platform
|
|
13
|
+
- **React Server Components** - Server-side rendering for better performance
|
|
14
|
+
- **next-intl** - Internationalization support
|
|
15
|
+
|
|
16
|
+
## Coding Standards
|
|
17
|
+
|
|
18
|
+
### TypeScript Standards
|
|
19
|
+
|
|
20
|
+
- Use **strict mode** in tsconfig.json
|
|
21
|
+
- Prefer type assertions over `any`: `value as ContentItem`
|
|
22
|
+
- Use discriminated unions for complex state management
|
|
23
|
+
- Enable strict null checks and strict function types
|
|
24
|
+
|
|
25
|
+
### Naming Conventions
|
|
26
|
+
|
|
27
|
+
- **Variables/Functions**: camelCase (`getUserData()`, `isLoading`, `currentUser`)
|
|
28
|
+
- **Components**: PascalCase (`SitecoreComponent`, `PageLayout`, `ContentBlock`)
|
|
29
|
+
- **Constants**: UPPER_SNAKE_CASE (`API_ENDPOINT`, `DEFAULT_TIMEOUT`)
|
|
30
|
+
- **Directories**: kebab-case (`src/components`, `src/api-clients`)
|
|
31
|
+
- **Types/Interfaces**: PascalCase (`ContentItem`, `LayoutProps`, `SitecoreConfig`)
|
|
32
|
+
|
|
33
|
+
### Modular Layout (App Router)
|
|
34
|
+
|
|
35
|
+
```
|
|
36
|
+
src/
|
|
37
|
+
app/ # App Router pages and layouts
|
|
38
|
+
components/ # UI components (React)
|
|
39
|
+
lib/ # Configuration and utilities
|
|
40
|
+
i18n/ # Internationalization setup
|
|
41
|
+
types/ # TypeScript type definitions
|
|
42
|
+
hooks/ # Custom React hooks
|
|
43
|
+
```
|
|
44
|
+
|
|
45
|
+
## Library Usage
|
|
46
|
+
|
|
47
|
+
### @sitecore-content-sdk
|
|
48
|
+
|
|
49
|
+
- Use `SitecoreClient` for content fetching
|
|
50
|
+
- Implement proper error handling with try/catch blocks
|
|
51
|
+
- Cache API responses using React Query or SWR
|
|
52
|
+
- Handle content preview vs. published content scenarios
|
|
53
|
+
|
|
54
|
+
```typescript
|
|
55
|
+
import { SitecoreClient } from '@sitecore-content-sdk/nextjs/client';
|
|
56
|
+
import scConfig from 'sitecore.config';
|
|
57
|
+
|
|
58
|
+
const client = new SitecoreClient({
|
|
59
|
+
...scConfig,
|
|
60
|
+
});
|
|
61
|
+
```
|
|
62
|
+
|
|
63
|
+
### React App Router Patterns
|
|
64
|
+
|
|
65
|
+
- Use **Server Components** for data fetching and static content (default)
|
|
66
|
+
- Use **Client Components** for interactivity (use 'use client' directive)
|
|
67
|
+
- Implement proper error boundaries with error.tsx
|
|
68
|
+
- Use loading.tsx for loading states
|
|
69
|
+
- Leverage layout.tsx for shared page structure
|
|
70
|
+
|
|
71
|
+
### Sitecore Field Components
|
|
72
|
+
|
|
73
|
+
- Always use Sitecore field components: `<Text>`, `<RichText>`, `<Image>`
|
|
74
|
+
- Validate field existence before rendering
|
|
75
|
+
- Handle empty/null fields gracefully
|
|
76
|
+
- Prefer Sitecore field components over manual rendering
|
|
77
|
+
|
|
78
|
+
```typescript
|
|
79
|
+
// Good: Using Sitecore field components
|
|
80
|
+
<Text field={fields?.title} tag="h1" />
|
|
81
|
+
<RichText field={fields?.content} />
|
|
82
|
+
<Image field={fields?.backgroundImage} />
|
|
83
|
+
|
|
84
|
+
// Avoid: Manual field value extraction unless necessary
|
|
85
|
+
```
|
|
86
|
+
|
|
87
|
+
## Example Patterns and Prompts
|
|
88
|
+
|
|
89
|
+
### Server Component Development
|
|
90
|
+
|
|
91
|
+
```typescript
|
|
92
|
+
// Server Component example (default in App Router)
|
|
93
|
+
import { SitecoreClient } from '@sitecore-content-sdk/nextjs/client';
|
|
94
|
+
import scConfig from 'sitecore.config';
|
|
95
|
+
|
|
96
|
+
const client = new SitecoreClient({
|
|
97
|
+
...scConfig,
|
|
98
|
+
});
|
|
99
|
+
|
|
100
|
+
export default async function SitecorePage({ params }: { params: { path: string[] } }) {
|
|
101
|
+
try {
|
|
102
|
+
const pageData = await client.getPage(params.path.join('/'));
|
|
103
|
+
return <SitecoreLayout layoutData={pageData?.layout} />;
|
|
104
|
+
} catch (error) {
|
|
105
|
+
return <div>Content not found</div>;
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
```
|
|
109
|
+
|
|
110
|
+
### Client Component Integration
|
|
111
|
+
|
|
112
|
+
Interactive Sitecore Components:
|
|
113
|
+
|
|
114
|
+
- Use 'use client' directive when needed
|
|
115
|
+
- Keep client components focused on interactivity
|
|
116
|
+
- Pass server-fetched data as props
|
|
117
|
+
- Handle hydration mismatches carefully
|
|
118
|
+
|
|
119
|
+
```typescript
|
|
120
|
+
'use client';
|
|
121
|
+
|
|
122
|
+
interface InteractiveSitecoreComponentProps {
|
|
123
|
+
fields: {
|
|
124
|
+
title: Field;
|
|
125
|
+
content: Field;
|
|
126
|
+
};
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
export default function InteractiveSitecoreComponent({
|
|
130
|
+
fields,
|
|
131
|
+
}: InteractiveSitecoreComponentProps) {
|
|
132
|
+
// Client-side interactivity here
|
|
133
|
+
return (
|
|
134
|
+
<div>
|
|
135
|
+
<Text field={fields?.title} tag="h2" />
|
|
136
|
+
<RichText field={fields?.content} />
|
|
137
|
+
</div>
|
|
138
|
+
);
|
|
139
|
+
}
|
|
140
|
+
```
|
|
141
|
+
|
|
142
|
+
### Component Development
|
|
143
|
+
|
|
144
|
+
```typescript
|
|
145
|
+
// Component props interface
|
|
146
|
+
interface HeroProps {
|
|
147
|
+
fields: {
|
|
148
|
+
title: Field;
|
|
149
|
+
subtitle: Field;
|
|
150
|
+
backgroundImage: Field;
|
|
151
|
+
};
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
export default function Hero({ fields }: HeroProps) {
|
|
155
|
+
return (
|
|
156
|
+
<div>
|
|
157
|
+
<Text field={fields?.title} tag="h1" />
|
|
158
|
+
<Text field={fields?.subtitle} tag="p" />
|
|
159
|
+
<Image field={fields?.backgroundImage} />
|
|
160
|
+
</div>
|
|
161
|
+
);
|
|
162
|
+
}
|
|
163
|
+
```
|
|
164
|
+
|
|
165
|
+
### Error Handling
|
|
166
|
+
|
|
167
|
+
API Calls:
|
|
168
|
+
|
|
169
|
+
- Always wrap in try/catch blocks
|
|
170
|
+
- Throw custom errors with context: `SitecoreFetchError`, `ConfigurationError`
|
|
171
|
+
- Handle edge cases with guard clauses
|
|
172
|
+
|
|
173
|
+
```typescript
|
|
174
|
+
async function fetchPageData(path: string): Promise<Page | null> {
|
|
175
|
+
if (!path) {
|
|
176
|
+
throw new Error('Page path is required');
|
|
177
|
+
}
|
|
178
|
+
|
|
179
|
+
try {
|
|
180
|
+
const pageData = await client.getPage(path);
|
|
181
|
+
return pageData;
|
|
182
|
+
} catch (error) {
|
|
183
|
+
throw new SitecoreFetchError(`Failed to fetch page data for ${path}`, error);
|
|
184
|
+
}
|
|
185
|
+
}
|
|
186
|
+
```
|
|
187
|
+
|
|
188
|
+
### Configuration
|
|
189
|
+
|
|
190
|
+
```typescript
|
|
191
|
+
// sitecore.config.ts
|
|
192
|
+
import { defineConfig } from '@sitecore-content-sdk/nextjs/config';
|
|
193
|
+
|
|
194
|
+
export default defineConfig({
|
|
195
|
+
api: {
|
|
196
|
+
edge: {
|
|
197
|
+
contextId: process.env.SITECORE_EDGE_CONTEXT_ID || '',
|
|
198
|
+
clientContextId: process.env.NEXT_PUBLIC_SITECORE_EDGE_CONTEXT_ID,
|
|
199
|
+
edgeUrl:
|
|
200
|
+
process.env.NEXT_PUBLIC_SITECORE_EDGE_PLATFORM_HOSTNAME ||
|
|
201
|
+
process.env.SITECORE_EDGE_PLATFORM_HOSTNAME ||
|
|
202
|
+
'https://edge-platform.sitecorecloud.io',
|
|
203
|
+
},
|
|
204
|
+
local: {
|
|
205
|
+
apiKey: process.env.SITECORE_API_KEY || '',
|
|
206
|
+
apiHost: process.env.SITECORE_API_HOST || '',
|
|
207
|
+
},
|
|
208
|
+
},
|
|
209
|
+
defaultSite: process.env.NEXT_PUBLIC_DEFAULT_SITE_NAME || 'default',
|
|
210
|
+
defaultLanguage: process.env.NEXT_PUBLIC_DEFAULT_LANGUAGE || 'en',
|
|
211
|
+
editingSecret: process.env.SITECORE_EDITING_SECRET,
|
|
212
|
+
});
|
|
213
|
+
```
|
|
214
|
+
|
|
215
|
+
### Internationalization
|
|
216
|
+
|
|
217
|
+
Multi-language Support:
|
|
218
|
+
|
|
219
|
+
- Configure next-intl for language routing
|
|
220
|
+
- Handle Sitecore language contexts
|
|
221
|
+
- Implement language switching
|
|
222
|
+
- Use proper locale-based data fetching
|
|
223
|
+
|
|
224
|
+
```typescript
|
|
225
|
+
// Language-aware data fetching
|
|
226
|
+
import { getTranslations } from 'next-intl/server';
|
|
227
|
+
|
|
228
|
+
export default async function LocalizedPage() {
|
|
229
|
+
const t = await getTranslations('common');
|
|
230
|
+
// Fetch Sitecore content for current locale
|
|
231
|
+
}
|
|
232
|
+
```
|
|
233
|
+
|
|
234
|
+
## Development Workflow
|
|
235
|
+
|
|
236
|
+
1. **Install dependencies**: `npm install`
|
|
237
|
+
2. **Configure environment**: Copy `.env.example` to `.env.local`
|
|
238
|
+
3. **Start development**: `npm run dev`
|
|
239
|
+
4. **Build for production**: `npm run build`
|
|
240
|
+
|
|
241
|
+
## App Router Best Practices
|
|
242
|
+
|
|
243
|
+
### Server vs Client Components
|
|
244
|
+
|
|
245
|
+
- Use Server Components for Sitecore content rendering (default)
|
|
246
|
+
- Use Client Components for user interactions
|
|
247
|
+
- Minimize client-side JavaScript
|
|
248
|
+
- Leverage server-side data fetching
|
|
249
|
+
|
|
250
|
+
### Routing and Layouts
|
|
251
|
+
|
|
252
|
+
- Use layout.tsx for shared page structure
|
|
253
|
+
- Implement loading.tsx for loading states
|
|
254
|
+
- Create error.tsx for error boundaries
|
|
255
|
+
- Use page.tsx for route content
|
|
256
|
+
- Use [...path] for Sitecore catch-all routes
|
|
257
|
+
|
|
258
|
+
### Performance Optimization
|
|
259
|
+
|
|
260
|
+
- Leverage Server Components for better performance
|
|
261
|
+
- Use streaming for improved loading experience
|
|
262
|
+
- Implement proper caching strategies
|
|
263
|
+
- Optimize images with Next.js Image component
|
|
264
|
+
|
|
265
|
+
## Best Practices
|
|
266
|
+
|
|
267
|
+
### Performance
|
|
268
|
+
|
|
269
|
+
- Optimize images using Next.js Image component
|
|
270
|
+
- Implement proper loading states
|
|
271
|
+
- Cache expensive operations appropriately
|
|
272
|
+
- Consider server-side rendering implications
|
|
273
|
+
- Lazy-load non-critical modules
|
|
274
|
+
- Use Server Components for better performance
|
|
275
|
+
|
|
276
|
+
### Security
|
|
277
|
+
|
|
278
|
+
- Sanitize user inputs before processing
|
|
279
|
+
- Validate data at application boundaries
|
|
280
|
+
- Use HTTPS for all Sitecore connections
|
|
281
|
+
- Never expose sensitive configuration in client-side code
|
|
282
|
+
- Escape content when rendering to prevent XSS
|
|
283
|
+
|
|
284
|
+
### Code Quality
|
|
285
|
+
|
|
286
|
+
- Follow DRY principle - extract common functionality
|
|
287
|
+
- Use SOLID principles for maintainable code
|
|
288
|
+
- Write self-documenting code with clear intent
|
|
289
|
+
- Implement proper error boundaries
|
|
290
|
+
- Test behavior, not implementation details
|
|
@@ -210,7 +210,7 @@ These are the main head-app–specific concepts. Details are in the sections bel
|
|
|
210
210
|
- **Skills.md** — Capability groupings for this app; [.agents/skills/](.agents/skills/) provides each capability as an Agent Skill (when-to-use, hard rules, stop conditions) for tools that support the [Agent Skills](https://agentskills.io) standard.
|
|
211
211
|
- **CLAUDE.md** — Full coding standards and Sitecore patterns for this template.
|
|
212
212
|
- **.cursor/rules/** — App Router and Sitecore rules.
|
|
213
|
-
- [Sitecore Content SDK](https://doc.sitecore.com/
|
|
213
|
+
- [Sitecore Content SDK](https://doc.sitecore.com/sai/en/developers/content-sdk/sitecore-content-sdk-for-sitecoreai.html) — Official docs.
|
|
214
214
|
- [Next.js App Router](https://nextjs.org/docs/app) — Routing, Server Components, data fetching.
|
|
215
215
|
- [next-intl](https://next-intl.dev/docs) — i18n routing and request config.
|
|
216
216
|
|
|
@@ -1,7 +1,3 @@
|
|
|
1
1
|
# Sitecore Content SDK Next.js App Router Sample Application
|
|
2
2
|
|
|
3
|
-
|
|
4
|
-
@TODO: Update link with appropriate page when avaiable
|
|
5
|
-
-->
|
|
6
|
-
|
|
7
|
-
[Documentation](https://doc.sitecore.com/xmc/en/developers/xm-cloud/sitecore-javascript-rendering-sdk--jss--for-next-js.html)
|
|
3
|
+
[SitecoreAI Content SDK Documentation](https://doc.sitecore.com/sai/en/developers/content-sdk/sitecore-content-sdk-for-sitecoreai.html)
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# Skills.md — Capability groupings for this app (Next.js App Router)
|
|
2
2
|
|
|
3
|
-
This file describes **this application** in terms of **capability-style groupings**: high-level areas that help AI tools and developers map tasks to the right part of the app. This is an App Router app with `[site]`/`[locale]` segments, next-intl, and separate server/client component maps. For concrete steps and patterns, see [AGENTS.md](AGENTS.md) and the [official Content SDK documentation](https://doc.sitecore.com/
|
|
3
|
+
This file describes **this application** in terms of **capability-style groupings**: high-level areas that help AI tools and developers map tasks to the right part of the app. This is an App Router app with `[site]`/`[locale]` segments, next-intl, and separate server/client component maps. For concrete steps and patterns, see [AGENTS.md](AGENTS.md) and the [official Content SDK documentation](https://doc.sitecore.com/sai/en/developers/content-sdk/sitecore-content-sdk-for-sitecoreai.html).
|
|
4
4
|
|
|
5
5
|
**Agent Skills:** Each grouping is also available as a skill in [.agents/skills/](.agents/skills/) in the standard [Agent Skills](https://agentskills.io) format (`SKILL.md` per capability). Tools that support this standard load skills from `.agents/skills/`; Cursor's built-in skills use `.cursor/skills/` unless it also supports the Agent Skills standard. The skills here are tailored for **App Router** (e.g. setRequestLocale, draftMode(), component-map.ts + component-map.client.ts).
|
|
6
6
|
|
|
@@ -74,6 +74,6 @@ Component data: layout data from getPage (or getPreview/getDesignLibraryData in
|
|
|
74
74
|
|
|
75
75
|
## How to use this
|
|
76
76
|
|
|
77
|
-
Map the task to one or more groupings above. Use [AGENTS.md](AGENTS.md) for app-level instructions and the [official documentation](https://doc.sitecore.com/
|
|
77
|
+
Map the task to one or more groupings above. Use [AGENTS.md](AGENTS.md) for app-level instructions and the [official documentation](https://doc.sitecore.com/sai/en/developers/content-sdk/sitecore-content-sdk-for-sitecoreai.html) for APIs.
|
|
78
78
|
|
|
79
79
|
**If your tool supports Agent Skills:** Load skills from [.agents/skills/](.agents/skills/) (one folder per capability). They provide when-to-use, hard rules, and stop conditions tailored for this App Router app.
|
|
@@ -1,29 +1,21 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import
|
|
3
|
-
import
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
"out/**",
|
|
23
|
-
"build/**",
|
|
24
|
-
"next-env.d.ts",
|
|
25
|
-
],
|
|
26
|
-
},
|
|
27
|
-
];
|
|
28
|
-
|
|
29
|
-
export default eslintConfig;
|
|
1
|
+
import { defineConfig, globalIgnores } from "eslint/config";
|
|
2
|
+
import nextVitals from "eslint-config-next/core-web-vitals";
|
|
3
|
+
import nextTs from "eslint-config-next/typescript";
|
|
4
|
+
|
|
5
|
+
export default defineConfig([
|
|
6
|
+
...nextVitals,
|
|
7
|
+
...nextTs,
|
|
8
|
+
{
|
|
9
|
+
rules: {
|
|
10
|
+
// Don't force alt for <Image/> (sourced from Sitecore media)
|
|
11
|
+
"jsx-a11y/alt-text": "off",
|
|
12
|
+
},
|
|
13
|
+
},
|
|
14
|
+
globalIgnores([
|
|
15
|
+
"node_modules/**",
|
|
16
|
+
".next/**",
|
|
17
|
+
"out/**",
|
|
18
|
+
"build/**",
|
|
19
|
+
"next-env.d.ts",
|
|
20
|
+
]),
|
|
21
|
+
]);
|