Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
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
645 changes: 471 additions & 174 deletions pnpm-lock.yaml

Large diffs are not rendered by default.

3 changes: 2 additions & 1 deletion pnpm-workspace.yaml
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
packages:
- 'packages/*'
- 'samples/*'
- '__test__/*'
- 'templates/*'
- '__test__/*'
43 changes: 43 additions & 0 deletions templates/alloy-template/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
# See https://help.github.com/articles/ignoring-files/ for more about ignoring files.

# dependencies
/node_modules
/.pnp
.pnp.*
.yarn/*
!.yarn/patches
!.yarn/plugins
!.yarn/releases
!.yarn/versions

# testing
/coverage

# next.js
/.next/
/out/

# production
/build

# misc
.DS_Store
*.pem

# debug
npm-debug.log*
yarn-debug.log*
yarn-error.log*
.pnpm-debug.log*

# env files (can opt-in for committing if needed)
.env*

# vercel
.vercel

# typescript
*.tsbuildinfo
next-env.d.ts

certificates
36 changes: 36 additions & 0 deletions templates/alloy-template/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
This is a [Next.js](https://nextjs.org) project bootstrapped with [`create-next-app`](https://nextjs.org/docs/app/api-reference/cli/create-next-app).

## Getting Started

First, run the development server:

```bash
npm run dev
# or
yarn dev
# or
pnpm dev
# or
bun dev
```

Open [http://localhost:3000](http://localhost:3000) with your browser to see the result.

You can start editing the page by modifying `app/page.tsx`. The page auto-updates as you edit the file.

This project uses [`next/font`](https://nextjs.org/docs/app/building-your-application/optimizing/fonts) to automatically optimize and load [Geist](https://vercel.com/font), a new font family for Vercel.

## Learn More

To learn more about Next.js, take a look at the following resources:

- [Next.js Documentation](https://nextjs.org/docs) - learn about Next.js features and API.
- [Learn Next.js](https://nextjs.org/learn) - an interactive Next.js tutorial.

You can check out [the Next.js GitHub repository](https://github.com/vercel/next.js) - your feedback and contributions are welcome!

## Deploy on Vercel

The easiest way to deploy your Next.js app is to use the [Vercel Platform](https://vercel.com/new?utm_medium=default-template&filter=next.js&utm_source=create-next-app&utm_campaign=create-next-app-readme) from the creators of Next.js.

Check out our [Next.js deployment documentation](https://nextjs.org/docs/app/building-your-application/deploying) for more details.
16 changes: 16 additions & 0 deletions templates/alloy-template/env.example
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
# Key to fetch content from the CMS.
# To get the key go to your CMS instance > Settings > API Keys
OPTIMIZELY_GRAPH_SINGLE_KEY='<SECRET>'

# Client ID and Secret from your CMS instance
# Go to your CMS instance > Settings > API Keys and click "Create API key"
OPTIMIZELY_CMS_CLIENT_ID=
OPTIMIZELY_CMS_CLIENT_SECRET=

# Root CMS instance. For example "https://<something>.cms.optimizely.com"
OPTIMIZELY_CMS_URL=
# From here, all environmental variables are optional
#
# Endpoint of GraphQL. Use this variable if you use a non-production instance or a different version
# OPTIMIZELY_GRAPH_URL=https://cg.optimizely.com/content/v2
#
17 changes: 17 additions & 0 deletions templates/alloy-template/next.config.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
import type { NextConfig } from 'next';

const nextConfig: NextConfig = {
images: {
domains: ['app-opinjssdk1sob7t001.cms.optimizely.com'],
remotePatterns: [
{
protocol: 'https',
hostname: '*.cms.optimizely.com',
port: '',
pathname: '/**',
},
],
},
};

export default nextConfig;
17 changes: 17 additions & 0 deletions templates/alloy-template/optimizely.config.mjs
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
import { buildConfig } from '@optimizely/cms-sdk';

export default buildConfig({
components: ['./src/components/*.tsx', './src/components/**/*.tsx'],
propertyGroups: [
{
key: 'SEO',
displayName: 'SEO',
sortOrder: 1,
},
{
key: 'SiteSettings',
displayName: 'Site Settings',
sortOrder: 2,
},
],
});
27 changes: 27 additions & 0 deletions templates/alloy-template/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
{
"name": "alloy-template",
"version": "0.1.0",
"private": true,
"scripts": {
"dev": "next dev --experimental-https",
"build": "next build",
"start": "next start"
},
"dependencies": {
"@optimizely/cms-sdk": "workspace:*",
"clsx": "^2.1.1",
"next": "15.5.4",
"react": "19.1.0",
"react-dom": "19.1.0",
"tailwind-merge": "^3.3.1"
},
"devDependencies": {
"@optimizely/cms-cli": "workspace:*",
"@tailwindcss/postcss": "^4",
"@types/node": "^20",
"@types/react": "^19",
"@types/react-dom": "^19",
"tailwindcss": "^4",
"typescript": "^5"
}
}
5 changes: 5 additions & 0 deletions templates/alloy-template/postcss.config.mjs
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
const config = {
plugins: ["@tailwindcss/postcss"],
};

export default config;
1 change: 1 addition & 0 deletions templates/alloy-template/public/file.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
1 change: 1 addition & 0 deletions templates/alloy-template/public/globe.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
1 change: 1 addition & 0 deletions templates/alloy-template/public/next.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
1 change: 1 addition & 0 deletions templates/alloy-template/public/vercel.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
1 change: 1 addition & 0 deletions templates/alloy-template/public/window.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
39 changes: 39 additions & 0 deletions templates/alloy-template/src/app/[...slug]/page.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
import Footer from '@/components/base/Footer';
import Header from '@/components/base/Header';
import { GraphClient } from '@optimizely/cms-sdk';
import { OptimizelyComponent } from '@optimizely/cms-sdk/react/server';
import { notFound } from 'next/navigation';
import React from 'react';

type Props = {
params: Promise<{
slug: string[];
}>;
};

export default async function Page({ params }: Props) {
const { slug } = await params;

const client = new GraphClient(process.env.OPTIMIZELY_GRAPH_SINGLE_KEY!, {
graphUrl: process.env.OPTIMIZELY_GRAPH_URL,
});
const path = `/${slug.join('/')}/`;
const c = await client.getContentByPath(path);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
const c = await client.getContentByPath(path);
const pages = await client.getContentByPath(path);


const children = (await client.getItems(path)) ?? [];
const ancestors = (await client.getPath(path)) ?? [];

if (c.length === 0) {
notFound();
}

return (
<>
<Header currentPath={{ children, ancestors }} />
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Wouldn't it make more sense to let this component load its own data?

<div className="container mx-auto p-10">
<OptimizelyComponent opti={c[0]} />
</div>
<Footer />
</>
);
}
Binary file added templates/alloy-template/src/app/favicon.ico
Binary file not shown.
26 changes: 26 additions & 0 deletions templates/alloy-template/src/app/globals.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
@import 'tailwindcss';

:root {
--background: #ffffff;
--foreground: #171717;
}

@theme inline {
--color-background: var(--background);
--color-foreground: var(--foreground);
--font-sans: var(--font-geist-sans);
--font-mono: var(--font-geist-mono);
}

/* @media (prefers-color-scheme: dark) {
:root {
--background: #0a0a0a;
--foreground: #ededed;
}
} */

body {
background: var(--background);
color: var(--foreground);
font-family: Arial, Helvetica, sans-serif;
}
83 changes: 83 additions & 0 deletions templates/alloy-template/src/app/layout.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
import type { Metadata } from 'next';
import { Geist, Geist_Mono } from 'next/font/google';
import {
BlankExperienceContentType,
initContentTypeRegistry,
} from '@optimizely/cms-sdk';
import { initReactComponentRegistry } from '@optimizely/cms-sdk/react/server';

import './globals.css';
import Teaser, { TeaserContentType } from '@/components/base/Teaser';
import Editorial, { EditorialContentType } from '@/components/base/Editorial';
import Contact, { ContactContentType } from '@/components/base/Contact';
import Start, { StartContentType } from '@/components/Start';
import Product, { ProductContentType } from '@/components/Product';
import Standard, { StandardContentType } from '@/components/Standard';
import Notice, { NoticeContentType } from '@/components/base/Notice';
import News, { NewsContentType } from '@/components/News';
import Article, { ArticleContentType } from '@/components/base/Article';
import BlankSection from '@/components/base/BlankSection';
import { SEOContentType } from '@/components/base/SEO';
import Button, { ButtonContentType } from '@/components/base/Button';

const geistSans = Geist({
variable: '--font-geist-sans',
subsets: ['latin'],
});

const geistMono = Geist_Mono({
variable: '--font-geist-mono',
subsets: ['latin'],
});

export const metadata: Metadata = {
title: 'Create Next App',
description: 'Generated by create next app',
};

initContentTypeRegistry([
ArticleContentType,
BlankExperienceContentType,
ContactContentType,
EditorialContentType,
NewsContentType,
NoticeContentType,
ProductContentType,
StartContentType,
TeaserContentType,
StandardContentType,
SEOContentType,
ButtonContentType,
]);

initReactComponentRegistry({
resolver: {
Article,
Contact,
Editorial,
News,
Notice,
Product,
Standard,
Start,
Teaser,
BlankSection,
Button,
},
});

export default async function RootLayout({
children,
}: Readonly<{
children: React.ReactNode;
}>) {
return (
<html lang="en">
<body
className={`${geistSans.variable} ${geistMono.variable} antialiased`}
>
{children}
</body>
</html>
);
}
3 changes: 3 additions & 0 deletions templates/alloy-template/src/app/page.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
export default function Home() {
return <></>;
}
35 changes: 35 additions & 0 deletions templates/alloy-template/src/app/preview/page.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
import { GraphClient, type PreviewParams } from '@optimizely/cms-sdk';
import { OptimizelyComponent } from '@optimizely/cms-sdk/react/server';
import { PreviewComponent } from '@optimizely/cms-sdk/react/client';
import Script from 'next/script';

type Props = {
searchParams: Promise<{ [key: string]: string | string[] | undefined }>;
};

export default async function Page({ searchParams }: Props) {
const client = new GraphClient(process.env.OPTIMIZELY_GRAPH_SINGLE_KEY!, {
graphUrl: process.env.OPTIMIZELY_GRAPH_URL,
});

const response = await client
.getPreviewContent(
// TODO: check types in runtime properly
(await searchParams) as PreviewParams
)
.catch((err) => {
console.log(err.errors);
console.log(err.request?.query);
throw err;
});

return (
<>
<Script
src={`${process.env.OPTIMIZELY_CMS_URL}/util/javascript/communicationinjector.js`}
></Script>
<PreviewComponent />
<OptimizelyComponent opti={response} />
</>
);
}
Loading