diff --git a/samples/uryga-template/.env.example b/samples/uryga-template/.env.example new file mode 100644 index 0000000..68bc57b --- /dev/null +++ b/samples/uryga-template/.env.example @@ -0,0 +1,17 @@ +# Key to fetch content from the CMS. +# To get the key go to your CMS instance > Settings > API Keys +OPTIMIZELY_GRAPH_SINGLE_KEY='' + +# 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://.cms.optimizely.com" +OPTIMIZELY_CMS_HOST= +OPTIMIZELY_GRAPH_URL="https://cg.optimizely.com/content/v2" + +## A secret key used for revalidating cached content. This should also be a secure, randomly generated string. +OPTIMIZELY_REVALIDATE_SECRET="" +## The Route URL of the Start Page. Examlpe: "/start-page" +OPTIMIZELY_START_PAGE_URL="" \ No newline at end of file diff --git a/samples/uryga-template/.gitignore b/samples/uryga-template/.gitignore new file mode 100644 index 0000000..149c0af --- /dev/null +++ b/samples/uryga-template/.gitignore @@ -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 \ No newline at end of file diff --git a/samples/uryga-template/.npmrc b/samples/uryga-template/.npmrc new file mode 100644 index 0000000..b02ceae --- /dev/null +++ b/samples/uryga-template/.npmrc @@ -0,0 +1 @@ +@episerver:registry=https://npm.pkg.github.com diff --git a/samples/uryga-template/.prettierignore b/samples/uryga-template/.prettierignore new file mode 100644 index 0000000..9ff7185 --- /dev/null +++ b/samples/uryga-template/.prettierignore @@ -0,0 +1,4 @@ +node_modules +.next +public +lib/optimizely/types/generated.ts \ No newline at end of file diff --git a/samples/uryga-template/.prettierrc b/samples/uryga-template/.prettierrc new file mode 100644 index 0000000..4449c24 --- /dev/null +++ b/samples/uryga-template/.prettierrc @@ -0,0 +1,7 @@ +{ + "semi": false, + "singleQuote": true, + "tabWidth": 2, + "trailingComma": "es5", + "plugins": ["prettier-plugin-tailwindcss"] +} diff --git a/samples/uryga-template/README.md b/samples/uryga-template/README.md new file mode 100644 index 0000000..e215bc4 --- /dev/null +++ b/samples/uryga-template/README.md @@ -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. diff --git a/samples/uryga-template/app/[locale]/[...slug]/page.tsx b/samples/uryga-template/app/[locale]/[...slug]/page.tsx new file mode 100644 index 0000000..3a72b33 --- /dev/null +++ b/samples/uryga-template/app/[locale]/[...slug]/page.tsx @@ -0,0 +1,59 @@ +import { generateAlternates } from '@/lib/metadata' +import { getAllPagesPaths } from '@/lib/optimizely/all-pages' +import { GraphClient } from '@episerver/cms-sdk' +import { OptimizelyComponent } from '@episerver/cms-sdk/react/server' +import { Metadata } from 'next' +import { notFound } from 'next/navigation' +import React from 'react' + +type Props = { + params: Promise<{ + slug: string[] + locale: string + }> +} + +export async function generateStaticParams() { + try { + return await getAllPagesPaths() + } catch (e) { + console.error('Error generating static params:', e) + return [] // Return an empty array on error to prevent build failures + } +} + +export async function generateMetadata(props: Props): Promise { + const { locale, slug } = await props.params + + const client = new GraphClient(process.env.OPTIMIZELY_GRAPH_SINGLE_KEY!, { + graphUrl: process.env.OPTIMIZELY_GRAPH_URL, + }) + + const formattedSlug = `/${slug.join('/')}/` + + const c = await client.fetchContent(`/${locale}${formattedSlug}`) + + return { + title: c?.title ?? '', + description: c?.shortDescription || '', + keywords: c?.keywords ?? '', + alternates: generateAlternates(locale, formattedSlug), + } +} + +export default async function Page({ params }: Props) { + const { slug, locale } = await params + + const client = new GraphClient(process.env.OPTIMIZELY_GRAPH_SINGLE_KEY!, { + graphUrl: process.env.OPTIMIZELY_GRAPH_URL, + }) + + try { + const c = await client.fetchContent(`/${locale}/${slug.join('/')}/`) + + return + } catch (error) { + console.error('Error fetching content:', error) + return notFound() + } +} diff --git a/samples/uryga-template/app/[locale]/layout.tsx b/samples/uryga-template/app/[locale]/layout.tsx new file mode 100644 index 0000000..2dc6454 --- /dev/null +++ b/samples/uryga-template/app/[locale]/layout.tsx @@ -0,0 +1,44 @@ +import { Geist, Geist_Mono } from 'next/font/google' +import { Header } from '@/components/layout/header' +import { Footer } from '@/components/layout/footer' +import { LOCALES } from '@/lib/optimizely/language' + +const geistSans = Geist({ + variable: '--font-geist-sans', + subsets: ['latin'], +}) + +const geistMono = Geist_Mono({ + variable: '--font-geist-mono', + subsets: ['latin'], +}) + +export function generateStaticParams() { + try { + return LOCALES.map((locale) => ({ locale })) + } catch (e) { + console.error(e) + return [] + } +} + +export default async function RootLayout({ + children, + params, +}: Readonly<{ + children: React.ReactNode + params: Promise<{ locale: string }> +}>) { + const { locale } = await params + return ( + + +
+
{children}
+