Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: add preview feature #19

Draft
wants to merge 26 commits into
base: main
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
26 commits
Select commit Hold shift + click to select a range
91253c4
make it sdk like
alexandrebodin Oct 3, 2024
33c29b2
feat: use latest strapi version for preview
remidej Nov 19, 2024
b7e8b89
feat: rewrite env variables setup guide
remidej Nov 19, 2024
a43eaa4
chore: delete cache revalidation panel
remidej Nov 19, 2024
95ffd7a
chore: reorder readme
remidej Nov 19, 2024
50d4bb6
docs: explain readme terminal steps
remidej Nov 20, 2024
cdb089c
enhancement: use new allowOrigins preview config
remidej Nov 20, 2024
edb957c
fix: leave draft mode for public data
remidej Nov 20, 2024
dbf5049
fix: comments
remidej Nov 20, 2024
e3d0c0e
fix: make allowedOrigins array
remidej Nov 20, 2024
ca08750
chore: bump strapi version
remidej Nov 28, 2024
394bd53
Merge remote-tracking branch 'origin/main' into feat/preview
remidej Nov 29, 2024
ff07789
fix: delete pnpm lock
remidej Nov 29, 2024
6ef83bc
fix: disable preview for some content types
remidej Nov 29, 2024
faa960b
fix: single types preview pathnames
remidej Nov 29, 2024
3e1aa82
chore: bump strapi
remidej Dec 5, 2024
6d0dc48
chore: remove draft banner
remidej Dec 11, 2024
bb44ccd
chore: revert unneeded changes
remidej Dec 11, 2024
eb2bdfa
chore: bump strapi
remidej Dec 11, 2024
36ded40
Merge remote-tracking branch 'origin/main' into feat/preview
remidej Dec 11, 2024
447bf5d
fix: build
remidej Dec 13, 2024
73e6932
fix: use yarn
remidej Dec 13, 2024
49d1257
fix: preview cache
remidej Dec 13, 2024
e17af76
chore: bump strapi
remidej Dec 13, 2024
1ecec85
chore: bump next
remidej Dec 16, 2024
08674ef
fix: disable fetchContentType cache
remidej Dec 17, 2024
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
17 changes: 9 additions & 8 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

![LaunchPad](./LaunchPad.jpg)

Welcome aboard **LaunchPad**, the official Strapi demo application, where we launch your content into the stratosphere at the speed of *"we-can't-even-measure-it!"*.
Welcome aboard **LaunchPad**, the official Strapi demo application, where we launch your content into the stratosphere at the speed of _"we-can't-even-measure-it!"_.
This repository contains the following:

- A Strapi project with content-types and data already onboard
Expand All @@ -17,14 +17,16 @@ Strap yourself in! You can get started with this project on your local machine b
Before you take off, make sure you have the right env variables loaded for each part (rocket science at its best):

Strapi (example in `./strapi/.env.example`):
- `STRAPI_ADMIN_CLIENT_URL=<url-of-nextjs>`
- `STRAPI_ADMIN_CLIENT_PREVIEW_SECRET=<a-random-token>`

- `STRAPI_ADMIN_CLIENT_URL=<url-of-nextjs>`
- `STRAPI_ADMIN_CLIENT_PREVIEW_SECRET=<a-random-token>`

- Create a `./strapi/.env` file with these variables

Next.js (example in `./next/.env.sample`):
- `NEXT_PUBLIC_API_URL=<url-of-strapi>` (mandatory)
- `PREVIEW_SECRET=<the-same-random-token-as-for-strapi>`

- `NEXT_PUBLIC_API_URL=<url-of-strapi>` (mandatory)
- `PREVIEW_SECRET=<the-same-random-token-as-for-strapi>`

- Create a `./next/.env` file with these variables

Expand Down Expand Up @@ -91,10 +93,9 @@ This installs dependencies, builds your project, and starts your server. You’r
[Data transfer](https://strapi.io/blog/importing-exporting-and-transferring-data-with-the-strapi-cli) Streams your data from one Strapi instance to another Strapi instance.<br />
[Review Worfklows](https://docs.strapi.io/user-docs/settings/review-workflows) Create and manage any desired review stages for your content, enabling your team to collaborate in the content creation flow from draft to publication. <br />


## Resources

[Docs](https://docs.strapi.io) • [Demo](https://strapi.io/demo) • [Forum](https://forum.strapi.io/) • [Discord](https://discord.strapi.io) • [Youtube](https://www.youtube.com/c/Strapi/featured) • [Strapi Design System](https://design-system.strapi.io/) • [Marketplace](https://market.strapi.io/) • [Clou Free Trial](https://cloud.strapi.io)
[Docs](https://docs.strapi.io) • [Demo](https://strapi.io/demo) • [Forum](https://forum.strapi.io/) • [Discord](https://discord.strapi.io) • [Youtube](https://www.youtube.com/c/Strapi/featured) • [Strapi Design System](https://design-system.strapi.io/) • [Marketplace](https://market.strapi.io/) • [Clou Free Trial](https://cloud.strapi.io)

## Todo

Expand All @@ -109,4 +110,4 @@ This installs dependencies, builds your project, and starts your server. You’r

- The Strapi application contains a postinstall script that will regenerate an uuid for the project in order to get some anonymous usage information concerning this demo. You can disable it by removing the uuid inside the `./strapi/packages.json` file.

- The Strapi application contains a patch for the @strapi/admin package. It is only necessary for the hosted demos since we automatically create the Super Admin users for them when they request this demo on our website.
- The Strapi application contains a patch for the @strapi/admin package. It is only necessary for the hosted demos since we automatically create the Super Admin users for them when they request this demo on our website.
4 changes: 2 additions & 2 deletions next/.env.sample → next/.env.example
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
WEBSITE_URL=http://localhost:3000 # Add the correct ENV var for this onto your hosting platform, point it to your production website.
PORT=3000

NEXT_PUBLIC_API_URL=url-of-strapi
PREVIEW_SECRET=the-same-random-token-as-for-strapi
NEXT_PUBLIC_API_URL=http://localhost:1337
PREVIEW_SECRET=tobemodified
39 changes: 26 additions & 13 deletions next/app/[locale]/(marketing)/[slug]/page.tsx
Original file line number Diff line number Diff line change
@@ -1,17 +1,23 @@
import { Metadata } from 'next';
import { Metadata } from "next";

import PageContent from '@/lib/shared/PageContent';
import fetchContentType from '@/lib/strapi/fetchContentType';
import { generateMetadataObject } from '@/lib/shared/metadata';
import PageContent from "@/lib/shared/PageContent";
import fetchContentType from "@/lib/strapi/fetchContentType";
import { generateMetadataObject } from "@/lib/shared/metadata";

export async function generateMetadata({
params,
}: {
params: { locale: string; slug: string };
}): Promise<Metadata> {
const pageData = await fetchContentType(
'pages',
`filters[slug][$eq]=${params.slug}&filters[locale][$eq]=${params.locale}&populate=seo.metaImage`,
"pages",
{
filters: {
slug: params.slug,
locale: params.locale,
},
populate: "seo.metaImage",
},
true
);

Expand All @@ -20,14 +26,21 @@ export async function generateMetadata({
return metadata;
}

export default async function Page({ params }: { params: { locale: string, slug: string } }) {
export default async function Page({
params,
}: {
params: { locale: string; slug: string };
}) {
const pageData = await fetchContentType(
'pages',
`filters[slug][$eq]=${params.slug}&filters[locale][$eq]=${params.locale}`,
"pages",
{
filters: {
slug: params.slug,
locale: params.locale,
},
},
true
);

return (
<PageContent pageData={pageData} />
);
}
return <PageContent pageData={pageData} />;
}
40 changes: 32 additions & 8 deletions next/app/[locale]/(marketing)/blog/[slug]/page.tsx
Original file line number Diff line number Diff line change
@@ -1,25 +1,49 @@
import { Metadata } from 'next';
import { Metadata } from "next";

import { BlogLayout } from "@/components/blog-layout";
import fetchContentType from "@/lib/strapi/fetchContentType";
import { BlocksRenderer } from '@strapi/blocks-react-renderer';
import { BlocksRenderer } from "@strapi/blocks-react-renderer";

import { generateMetadataObject } from '@/lib/shared/metadata';
import { generateMetadataObject } from "@/lib/shared/metadata";

export async function generateMetadata({
params,
}: {
params: { locale: string, slug: string };
params: { locale: string; slug: string };
}): Promise<Metadata> {
const pageData = await fetchContentType("articles", `filters[slug]=${params?.slug}&filters[locale][$eq]=${params.locale}&populate=seo.metaImage`, true)
const pageData = await fetchContentType(
"articles",
{
filters: {
slug: params.slug,
locale: params.locale,
},
populate: "seo.metaImage",
},
true
);

const seo = pageData?.seo;
const metadata = generateMetadataObject(seo);
return metadata;
}

export default async function singleArticlePage({ params }: { params: { slug: string, locale: string } }) {
const article = await fetchContentType("articles", `filters[slug]=${params?.slug}&filters[locale][$eq]=${params.locale}`, true)
export default async function singleArticlePage({
params,
}: {
params: { slug: string; locale: string };
}) {
const article = await fetchContentType(
"articles",
// `filters[slug]=${params?.slug}&filters[locale][$eq]=${params.locale}`,
{
filters: {
slug: params.slug,
locale: params.locale,
},
},
true
);

if (!article) {
return <div>Blog not found</div>;
Expand All @@ -30,4 +54,4 @@ export default async function singleArticlePage({ params }: { params: { slug: st
<BlocksRenderer content={article.content} />
</BlogLayout>
);
}
}
36 changes: 25 additions & 11 deletions next/app/[locale]/(marketing)/blog/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,28 +9,38 @@ import { BlogPostRows } from "@/components/blog-post-rows";
import { AmbientColor } from "@/components/decorations/ambient-color";
import fetchContentType from "@/lib/strapi/fetchContentType";
import { Article } from "@/types/types";
import { generateMetadataObject } from '@/lib/shared/metadata';

import { generateMetadataObject } from "@/lib/shared/metadata";

export async function generateMetadata({
params,
}: {
params: { locale: string };
}): Promise<Metadata> {
const pageData = await fetchContentType('blog-page', `filters[locale]=${params.locale}&populate=seo.metaImage`, true)
const pageData = await fetchContentType(
"blog-page",
{
filters: { locale: params.locale },
populate: "seo.metaImage",
},
true
);

const seo = pageData?.seo;
const metadata = generateMetadataObject(seo);
return metadata;
}

export default async function Blog({
params,
}: {
params: { locale: string };
}) {
const blogPage = await fetchContentType('blog-page', `filters[locale]=${params.locale}`, true)
const articles = await fetchContentType('articles', `filters[locale]=${params.locale}`)
export default async function Blog({ params }: { params: { locale: string } }) {
const blogPage = await fetchContentType(
"blog-page",
{
filters: { locale: params.locale },
},
true
);
const articles = await fetchContentType("articles", {
filters: { locale: params.locale },
});

return (
<div className="relative overflow-hidden py-20 md:py-0">
Expand All @@ -49,7 +59,11 @@ export default async function Blog({
</div>

{articles.data.slice(0, 1).map((article: Article) => (
<BlogCard article={article} locale={params.locale} key={article.title} />
<BlogCard
article={article}
locale={params.locale}
key={article.title}
/>
))}

<BlogPostRows articles={articles.data} />
Expand Down
33 changes: 24 additions & 9 deletions next/app/[locale]/(marketing)/page.tsx
Original file line number Diff line number Diff line change
@@ -1,17 +1,23 @@
import { Metadata } from 'next';
import { Metadata } from "next";

import PageContent from '@/lib/shared/PageContent';
import fetchContentType from '@/lib/strapi/fetchContentType';
import { generateMetadataObject } from '@/lib/shared/metadata';
import PageContent from "@/lib/shared/PageContent";
import fetchContentType from "@/lib/strapi/fetchContentType";
import { generateMetadataObject } from "@/lib/shared/metadata";

export async function generateMetadata({
params,
}: {
params: { locale: string };
}): Promise<Metadata> {
const pageData = await fetchContentType(
'pages',
`filters[slug][$eq]=homepage&filters[locale][$eq]=${params.locale}&populate=seo.metaImage`,
"pages",
{
filters: {
slug: "homepage",
locale: params.locale,
},
populate: "seo.metaImage",
},
true
);

Expand All @@ -20,10 +26,19 @@ export async function generateMetadata({
return metadata;
}

export default async function HomePage({ params }: { params: { locale: string } }) {
export default async function HomePage({
params,
}: {
params: { locale: string };
}) {
const pageData = await fetchContentType(
'pages',
`filters[slug][$eq]=homepage&filters[locale][$eq]=${params.locale}`,
"pages",
{
filters: {
slug: "homepage",
locale: params.locale,
},
},
true
);

Expand Down
32 changes: 25 additions & 7 deletions next/app/[locale]/(marketing)/products/[slug]/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,17 +3,24 @@ import { redirect } from "next/navigation";
import { Container } from "@/components/container";
import { AmbientColor } from "@/components/decorations/ambient-color";
import { SingleProduct } from "@/components/products/single-product";
import DynamicZoneManager from '@/components/dynamic-zone/manager'
import { generateMetadataObject } from '@/lib/shared/metadata';
import DynamicZoneManager from "@/components/dynamic-zone/manager";
import { generateMetadataObject } from "@/lib/shared/metadata";

import fetchContentType from "@/lib/strapi/fetchContentType";

export async function generateMetadata({
params,
}: {
params: { locale: string, slug: string };
params: { locale: string; slug: string };
}): Promise<Metadata> {
const pageData = await fetchContentType("products", `filters[slug]=${params?.slug}&populate=seo.metaImage`, true)
const pageData = await fetchContentType(
"products",
{
filters: { slug: params.slug },
populate: "seo.metaImage",
},
true
);

const seo = pageData?.seo;
const metadata = generateMetadataObject(seo);
Expand All @@ -23,9 +30,15 @@ export async function generateMetadata({
export default async function SingleProductPage({
params,
}: {
params: { slug: string, locale: string };
params: { slug: string; locale: string };
}) {
const product = await fetchContentType("products", `filters[slug]=${params?.slug}`, true)
const product = await fetchContentType(
"products",
{
filters: { slug: params.slug },
},
true
);

if (!product) {
redirect("/products");
Expand All @@ -36,7 +49,12 @@ export default async function SingleProductPage({
<AmbientColor />
<Container className="py-20 md:py-40">
<SingleProduct product={product} />
{product?.dynamic_zone && (<DynamicZoneManager dynamicZone={product?.dynamic_zone} locale={params.locale} />)}
{product?.dynamic_zone && (
<DynamicZoneManager
dynamicZone={product?.dynamic_zone}
locale={params.locale}
/>
)}
</Container>
</div>
);
Expand Down
Loading