UNPKG

@posthog/nextjs-config

Version:

NextJS configuration helper for Posthog 🦔

86 lines (85 loc) • 4.53 kB
import { PosthogWebpackPlugin, resolveConfig } from "@posthog/webpack-plugin"; import { hasCompilerHook, isTurbopackEnabled, processSourceMaps } from "./utils.mjs"; import { stripDanglingSourceMapComments } from "./strip-sourcemap-comments.mjs"; const INVOCATION_TIMEOUT_MS = 5000; function withPostHogConfig(userNextConfig, posthogConfig) { const resolvedConfig = resolveConfig(posthogConfig); const sourceMapEnabled = resolvedConfig.sourcemaps.enabled; const isCompilerHookSupported = hasCompilerHook(); const turbopackEnabled = isTurbopackEnabled(); if (turbopackEnabled && !isCompilerHookSupported) console.warn('[@posthog/nextjs-config] Turbopack support is only available with next version >= 15.4.1'); let invoked = false; const nextConfigFn = async (phase, param)=>{ let { defaultConfig } = param; invoked = true; const { webpack: userWebPackConfig, compiler: userCompilerConfig, distDir, ...userConfig } = await resolveUserConfig(userNextConfig, phase, defaultConfig); const nextConfig = { ...userConfig, distDir, webpack: withWebpackConfig(userWebPackConfig, resolvedConfig), compiler: withCompilerConfig(userCompilerConfig, resolvedConfig) }; if (turbopackEnabled && sourceMapEnabled) nextConfig.productionBrowserSourceMaps = true; return nextConfig; }; if ('function' == typeof setTimeout) { var _timer_unref; const timer = setTimeout(()=>{ if (!invoked) console.warn("[@posthog/nextjs-config] withPostHogConfig was loaded but Next.js never invoked the config function it returns. This usually means another config wrapper (e.g. withNextIntl, withSentryConfig) is wrapping withPostHogConfig and producing a plain object that drops the PostHog hooks. Move withPostHogConfig(...) to be the OUTERMOST wrapper in next.config.js so source maps upload and other build hooks run. See https://github.com/PostHog/posthog-js/issues/3572"); }, INVOCATION_TIMEOUT_MS); null == (_timer_unref = timer.unref) || _timer_unref.call(timer); } return nextConfigFn; } function resolveUserConfig(userNextConfig, phase, defaultConfig) { if ('function' == typeof userNextConfig) { const maybePromise = userNextConfig(phase, { defaultConfig }); if (maybePromise instanceof Promise) return maybePromise; return Promise.resolve(maybePromise); } if ('object' == typeof userNextConfig) return Promise.resolve(userNextConfig); throw new Error('Invalid user config'); } function withWebpackConfig(userWebpackConfig, posthogConfig) { const defaultWebpackConfig = userWebpackConfig || ((config)=>config); const sourceMapEnabled = posthogConfig.sourcemaps.enabled; const turbopackEnabled = isTurbopackEnabled(); return (config, options)=>{ const webpackConfig = defaultWebpackConfig(config, options); const isServer = options.isServer; if (sourceMapEnabled) { if (!turbopackEnabled) { webpackConfig.plugins = webpackConfig.plugins || []; let currentConfig = posthogConfig; if (isServer) currentConfig = { ...posthogConfig, sourcemaps: { ...posthogConfig.sourcemaps, deleteAfterUpload: false } }; webpackConfig.plugins.push(new PosthogWebpackPlugin(currentConfig, true)); } } return webpackConfig; }; } function withCompilerConfig(userCompilerConfig, posthogConfig) { const sourceMapEnabled = posthogConfig.sourcemaps.enabled; const turbopackEnabled = isTurbopackEnabled(); if (sourceMapEnabled && turbopackEnabled && hasCompilerHook()) { const newConfig = userCompilerConfig || {}; const userCompilerHook = null == userCompilerConfig ? void 0 : userCompilerConfig.runAfterProductionCompile; newConfig.runAfterProductionCompile = async (config)=>{ await (null == userCompilerHook ? void 0 : userCompilerHook(config)); console.debug('Processing source maps from compilation hook...'); await processSourceMaps(posthogConfig, config.distDir); if (posthogConfig.sourcemaps.deleteAfterUpload) await stripDanglingSourceMapComments(config.distDir); }; return newConfig; } return userCompilerConfig; } export { withPostHogConfig };