Skip to content
Merged
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
135 changes: 0 additions & 135 deletions docusaurus/docs/cms/features/preview.md
Original file line number Diff line number Diff line change
Expand Up @@ -428,141 +428,6 @@ const pageData = await fetchContentType('api::page.page', {
});
```

#### 6. [Front end] Detect changes in Strapi and refresh the front-end {#6-refresh-frontend}

Strapi emits a `strapiUpdate` message to inform the front end that data has changed.

To track this, within your front-end application, add an event listener to listen to events posted through [the `postMessage()` API](https://developer.mozilla.org/en-US/docs/Web/API/Window/postMessage) on the `window` object. The listener needs to filter through messages and react only to Strapi-initiated messages, then refresh the iframe content.

With Next.js, the recommended way to refresh the iframe content is with <ExternalLink to="https://nextjs.org/docs/app/building-your-application/caching#routerrefresh" text="the `router.refresh()` method" />.

<Tabs groupId="js-ts">
<TabItem value="js" label="JavaScript" >

```tsx title="next/app/path/to/your/front/end/logic.jsx" {6-17}
export default function MyClientComponent({...props}) {
// …
const router = useRouter();

useEffect(() => {
const handleMessage = async (message) => {
if (
// Filters events emitted through the postMessage() API
message.origin === process.env.NEXT_PUBLIC_API_URL &&
message.data.type === "strapiUpdate"
) { // Recommended way to refresh with Next.js
router.refresh();
}
};

// Add the event listener
window.addEventListener("message", handleMessage);

// Cleanup the event listener on unmount
return () => {
window.removeEventListener("message", handleMessage);
};
}, [router]);

// ...
}
```

</TabItem>
<TabItem value="ts" label="TypeScript" >

```tsx title="next/app/path/to/your/front/end/logic.tsx" {6-17}
export default function MyClientComponent({
//…
const router = useRouter();

useEffect(() => {
const handleMessage = async (message: MessageEvent<any>) => {
if (
// Filters events emitted through the postMessage() API
message.origin === process.env.NEXT_PUBLIC_API_URL &&
message.data.type === "strapiUpdate"
) { // Recommended way to refresh with Next.js
router.refresh();
}
};

// Add the event listener
window.addEventListener("message", handleMessage);

// Cleanup the event listener on unmount
return () => {
window.removeEventListener("message", handleMessage);
};
}, [router]);

// …
})
```

</TabItem>

</Tabs>

<details>
<summary>Caching in Next.js:</summary>

In Next.js, [cache persistence](https://nextjs.org/docs/app/building-your-application/caching) may require additional steps. You might need to invalidate the cache by making an API call from the client side to the server, where the revalidation logic will be handled. Please refer to Next.js documentation for details, for instance with the [revalidatePath() method](https://nextjs.org/docs/app/building-your-application/caching#revalidatepath).
<br/>

</details>

#### [Front end] Next steps

Once the preview system is set up, you need to adapt your data fetching logic to handle draft content appropriately. This involves the following steps:

1. Create or adapt your data fetching utility to check if draft mode is enabled
2. Update your API calls to include the draft status parameter when appropriate

The following, taken from the <ExternalLink to="https://github.com/strapi/LaunchPad/tree/feat/preview" text="Launchpad" /> Strapi demo application, is an example of how to implement draft-aware data fetching in your Next.js front-end application:

```typescript {8-18}
import { draftMode } from "next/headers";
import qs from "qs";

export default async function fetchContentType(
contentType: string,
params: Record = {}
): Promise {
// Check if Next.js draft mode is enabled
const { isEnabled: isDraftMode } = draftMode();

try {
const queryParams = { ...params };
// Add status=draft parameter when draft mode is enabled
if (isDraftMode) {
queryParams.status = "draft";
}

const url = `${baseURL}/${contentType}?${qs.stringify(queryParams)}`;
const response = await fetch(url);
if (!response.ok) {
throw new Error(
`Failed to fetch data from Strapi (url=${url}, status=${response.status})`
);
}
return await response.json();
} catch (error) {
console.error("Error fetching content:", error);
throw error;
}
}
```

This utility method can then be used in your page components to fetch either draft or published content based on the preview state:

```typescript
// In your page component:
const pageData = await fetchContentType('api::page.page', {
// Your other query parameters
});
```

## Usage

**Path to use the feature:** <Icon name="feather" /> Content Manager, edit view of your content type
Expand Down