import type { Core, UID } from "@strapi/strapi"; /** * Generate preview pathname based on content type and document * @param {string} uid - Content type identifier (e.g., 'api::article.article') * @param {object} options - Options containing locale and document data * @returns {string|null} - The preview pathname or null if no preview available */ const getPreviewPathname = (uid, { locale, document }) => { const { slug } = document || {}; switch (uid) { // Global single type - preview on homepage case "api::global.global": return "/"; // Generic pages with slugs case "api::page.page": if (!slug) { return null; // No slug, no preview } return `/${slug}`; // Articles/blog posts case "api::article.article": if (!slug) { return "/articles"; // Could redirect to articles index } return `/articles/${slug}`; // Products (example) case "api::product.product": if (!slug) { return "/products"; } return `/products/${slug}`; // Add more content types as needed default: // Return null for content types that shouldn't have previews // (e.g., configuration, metadata, components) return null; } }; const config = ({ env, }: Core.Config.Shared.ConfigParams): Core.Config.Admin => { const clientUrl = env("CLIENT_URL"); const previewSecret = env("PREVIEW_SECRET"); return { auth: { secret: env("ADMIN_JWT_SECRET"), }, apiToken: { salt: env("API_TOKEN_SALT"), }, transfer: { token: { salt: env("TRANSFER_TOKEN_SALT"), }, }, secrets: { encryptionKey: env("ENCRYPTION_KEY"), }, flags: { nps: env.bool("FLAG_NPS", true), promoteEE: env.bool("FLAG_PROMOTE_EE", true), }, // Preview preview: { enabled: true, config: { // Allow preview iframe to load from your frontend domain allowedOrigins: [clientUrl], /** * Preview handler - generates preview URLs for content * @param {string} uid - Content type UID * @param {object} context - Preview context * @param {string} context.documentId - Document ID being previewed * @param {string} context.locale - Document locale * @param {string} context.status - Document status ('draft' or 'published') * @returns {string|null} - Preview URL or null to disable preview */ async handler(uid, { documentId, locale, status }) { try { // Fetch the complete document from Strapi const document = await strapi .documents(uid as UID.ContentType) .findOne({ documentId, // Ensure we get the correct version based on status ...(status === "draft" && { status: "draft" }), }); // Generate the preview pathname const pathname = getPreviewPathname(uid, { locale, document }); // If no pathname is generated, disable preview for this content type if (!pathname) { return null; } // Build preview URL with all necessary parameters const urlSearchParams = new URLSearchParams({ path: pathname, secret: previewSecret, status: status || "draft", documentId, uid, ...(locale && { locale }), }); // Return the complete preview URL pointing to your Vike app's preview API return `${clientUrl}/api/preview?${urlSearchParams}`; } catch (error) { console.error("Preview handler error:", error); return null; } }, }, }, }; }; export default config;