diff --git a/web/app/(commonLayout)/app/(appDetailLayout)/[appId]/layout-main.tsx b/web/app/(commonLayout)/app/(appDetailLayout)/[appId]/layout-main.tsx index fd0bf2c8bd4947..6f60899c85f682 100644 --- a/web/app/(commonLayout)/app/(appDetailLayout)/[appId]/layout-main.tsx +++ b/web/app/(commonLayout)/app/(appDetailLayout)/[appId]/layout-main.tsx @@ -13,7 +13,6 @@ import { RiTerminalWindowLine, } from '@remixicon/react' import { useUnmount } from 'ahooks' -import dynamic from 'next/dynamic' import { usePathname, useRouter } from 'next/navigation' import * as React from 'react' import { useCallback, useEffect, useState } from 'react' @@ -26,6 +25,7 @@ import { useStore as useTagStore } from '@/app/components/base/tag-management/st import { useAppContext } from '@/context/app-context' import useBreakpoints, { MediaType } from '@/hooks/use-breakpoints' import useDocumentTitle from '@/hooks/use-document-title' +import dynamic from '@/next/dynamic' import { fetchAppDetailDirect } from '@/service/apps' import { AppModeEnum } from '@/types/app' import { cn } from '@/utils/classnames' diff --git a/web/app/components/app-sidebar/app-info/app-info-modals.tsx b/web/app/components/app-sidebar/app-info/app-info-modals.tsx index 4ca7f6adbce089..232afb18c783d4 100644 --- a/web/app/components/app-sidebar/app-info/app-info-modals.tsx +++ b/web/app/components/app-sidebar/app-info/app-info-modals.tsx @@ -3,9 +3,9 @@ import type { DuplicateAppModalProps } from '@/app/components/app/duplicate-moda import type { CreateAppModalProps } from '@/app/components/explore/create-app-modal' import type { EnvironmentVariable } from '@/app/components/workflow/types' import type { App, AppSSO } from '@/types/app' -import dynamic from 'next/dynamic' import * as React from 'react' import { useTranslation } from 'react-i18next' +import dynamic from '@/next/dynamic' const SwitchAppModal = dynamic(() => import('@/app/components/app/switch-app-modal'), { ssr: false }) const CreateAppModal = dynamic(() => import('@/app/components/explore/create-app-modal'), { ssr: false }) diff --git a/web/app/components/apps/app-card.tsx b/web/app/components/apps/app-card.tsx index 471b3420d10027..6a4a2181d6e778 100644 --- a/web/app/components/apps/app-card.tsx +++ b/web/app/components/apps/app-card.tsx @@ -7,7 +7,6 @@ import type { CreateAppModalProps } from '@/app/components/explore/create-app-mo import type { EnvironmentVariable } from '@/app/components/workflow/types' import type { App } from '@/types/app' import { RiBuildingLine, RiGlobalLine, RiLockLine, RiMoreFill, RiVerifiedBadgeLine } from '@remixicon/react' -import dynamic from 'next/dynamic' import { useRouter } from 'next/navigation' import * as React from 'react' import { useCallback, useEffect, useMemo, useState } from 'react' @@ -36,6 +35,7 @@ import { useGlobalPublicStore } from '@/context/global-public-context' import { useProviderContext } from '@/context/provider-context' import { useAsyncWindowOpen } from '@/hooks/use-async-window-open' import { AccessMode } from '@/models/access-control' +import dynamic from '@/next/dynamic' import { useGetUserCanAccessApp } from '@/service/access-control' import { copyApp, exportAppConfig, updateAppInfo } from '@/service/apps' import { fetchInstalledAppList } from '@/service/explore' diff --git a/web/app/components/apps/list.tsx b/web/app/components/apps/list.tsx index 6ae422f7162910..0d52bd468cfcc4 100644 --- a/web/app/components/apps/list.tsx +++ b/web/app/components/apps/list.tsx @@ -2,7 +2,6 @@ import type { FC } from 'react' import { useDebounceFn } from 'ahooks' -import dynamic from 'next/dynamic' import { parseAsStringLiteral, useQueryState } from 'nuqs' import { useCallback, useEffect, useRef, useState } from 'react' import { useTranslation } from 'react-i18next' @@ -15,6 +14,7 @@ import { NEED_REFRESH_APP_LIST_KEY } from '@/config' import { useAppContext } from '@/context/app-context' import { useGlobalPublicStore } from '@/context/global-public-context' import { CheckModal } from '@/hooks/use-pay' +import dynamic from '@/next/dynamic' import { useInfiniteAppList } from '@/service/use-apps' import { AppModeEnum, AppModes } from '@/types/app' import { cn } from '@/utils/classnames' diff --git a/web/app/components/apps/new-app-card.tsx b/web/app/components/apps/new-app-card.tsx index 868da0dcb53ab5..a14b10098f1eb6 100644 --- a/web/app/components/apps/new-app-card.tsx +++ b/web/app/components/apps/new-app-card.tsx @@ -1,6 +1,5 @@ 'use client' -import dynamic from 'next/dynamic' import { useRouter, useSearchParams, @@ -13,6 +12,7 @@ import { CreateFromDSLModalTab } from '@/app/components/app/create-from-dsl-moda import { FileArrow01, FilePlus01, FilePlus02 } from '@/app/components/base/icons/src/vender/line/files' import AppListContext from '@/context/app-list-context' import { useProviderContext } from '@/context/provider-context' +import dynamic from '@/next/dynamic' import { cn } from '@/utils/classnames' const CreateAppModal = dynamic(() => import('@/app/components/app/create-app-modal'), { diff --git a/web/app/components/base/file-uploader/dynamic-pdf-preview.tsx b/web/app/components/base/file-uploader/dynamic-pdf-preview.tsx index 116db89864c865..225d5664c2c383 100644 --- a/web/app/components/base/file-uploader/dynamic-pdf-preview.tsx +++ b/web/app/components/base/file-uploader/dynamic-pdf-preview.tsx @@ -1,6 +1,6 @@ 'use client' -import dynamic from 'next/dynamic' +import dynamic from '@/next/dynamic' type DynamicPdfPreviewProps = { url: string diff --git a/web/app/components/base/ga/index.tsx b/web/app/components/base/ga/index.tsx index 7225dcf4287771..3e19afd9744b3e 100644 --- a/web/app/components/base/ga/index.tsx +++ b/web/app/components/base/ga/index.tsx @@ -1,8 +1,8 @@ import type { FC } from 'react' -import { headers } from 'next/headers' -import Script from 'next/script' import * as React from 'react' import { IS_CE_EDITION, IS_PROD } from '@/config' +import { headers } from '@/next/headers' +import Script from '@/next/script' export enum GaType { admin = 'admin', diff --git a/web/app/components/base/markdown-blocks/code-block.tsx b/web/app/components/base/markdown-blocks/code-block.tsx index 837929cfffae6e..b36d8d778853a7 100644 --- a/web/app/components/base/markdown-blocks/code-block.tsx +++ b/web/app/components/base/markdown-blocks/code-block.tsx @@ -1,5 +1,4 @@ import ReactEcharts from 'echarts-for-react' -import dynamic from 'next/dynamic' import { memo, useCallback, useEffect, useMemo, useRef, useState } from 'react' import SyntaxHighlighter from 'react-syntax-highlighter' import { @@ -12,6 +11,7 @@ import MarkdownMusic from '@/app/components/base/markdown-blocks/music' import ErrorBoundary from '@/app/components/base/markdown/error-boundary' import SVGBtn from '@/app/components/base/svg' import useTheme from '@/hooks/use-theme' +import dynamic from '@/next/dynamic' import { Theme } from '@/types/app' import SVGRenderer from '../svg-gallery' // Assumes svg-gallery.tsx is in /base directory diff --git a/web/app/components/base/markdown/index.tsx b/web/app/components/base/markdown/index.tsx index 6faee9c260a958..5915816d7acd47 100644 --- a/web/app/components/base/markdown/index.tsx +++ b/web/app/components/base/markdown/index.tsx @@ -1,7 +1,7 @@ import type { SimplePluginInfo, StreamdownWrapperProps } from './streamdown-wrapper' import { flow } from 'es-toolkit/compat' -import dynamic from 'next/dynamic' import { memo, useMemo } from 'react' +import dynamic from '@/next/dynamic' import { cn } from '@/utils/classnames' import { preprocessLaTeX, preprocessThinkTag } from './markdown-utils' diff --git a/web/app/components/base/markdown/streamdown-wrapper.tsx b/web/app/components/base/markdown/streamdown-wrapper.tsx index 6fdf954edcb05f..46db301adbd52c 100644 --- a/web/app/components/base/markdown/streamdown-wrapper.tsx +++ b/web/app/components/base/markdown/streamdown-wrapper.tsx @@ -1,7 +1,6 @@ import type { ComponentType } from 'react' import type { Components, StreamdownProps } from 'streamdown' import { createMathPlugin } from '@streamdown/math' -import dynamic from 'next/dynamic' import { memo, useMemo } from 'react' import RemarkBreaks from 'remark-breaks' import { defaultRehypePlugins, defaultRemarkPlugins, Streamdown } from 'streamdown' @@ -18,6 +17,7 @@ import { VideoBlock, } from '@/app/components/base/markdown-blocks' import { ENABLE_SINGLE_DOLLAR_LATEX } from '@/config' +import dynamic from '@/next/dynamic' import { customUrlTransform } from './markdown-utils' import 'katex/dist/katex.min.css' diff --git a/web/app/components/base/zendesk/index.tsx b/web/app/components/base/zendesk/index.tsx index 4879725c851cf8..20f4f84baf3cb9 100644 --- a/web/app/components/base/zendesk/index.tsx +++ b/web/app/components/base/zendesk/index.tsx @@ -1,7 +1,7 @@ -import { headers } from 'next/headers' -import Script from 'next/script' import { memo } from 'react' import { IS_CE_EDITION, IS_PROD, ZENDESK_WIDGET_KEY } from '@/config' +import { headers } from '@/next/headers' +import Script from '@/next/script' const Zendesk = async () => { if (IS_CE_EDITION || !ZENDESK_WIDGET_KEY) diff --git a/web/app/components/datasets/create/file-uploader/components/file-list-item.tsx b/web/app/components/datasets/create/file-uploader/components/file-list-item.tsx index d36773fa5cf921..2f51a9f76729c3 100644 --- a/web/app/components/datasets/create/file-uploader/components/file-list-item.tsx +++ b/web/app/components/datasets/create/file-uploader/components/file-list-item.tsx @@ -1,10 +1,10 @@ 'use client' import type { CustomFile as File, FileItem } from '@/models/datasets' import { RiDeleteBinLine, RiErrorWarningFill } from '@remixicon/react' -import dynamic from 'next/dynamic' import { useMemo } from 'react' import DocumentFileIcon from '@/app/components/datasets/common/document-file-icon' import useTheme from '@/hooks/use-theme' +import dynamic from '@/next/dynamic' import { Theme } from '@/types/app' import { formatFileSize, getFileExtension } from '@/utils/format' import { PROGRESS_COMPLETE, PROGRESS_ERROR } from '../constants' diff --git a/web/app/components/datasets/documents/create-from-pipeline/data-source/local-file/components/file-list-item.tsx b/web/app/components/datasets/documents/create-from-pipeline/data-source/local-file/components/file-list-item.tsx index 1a61fa04f08282..4338dd05d468fc 100644 --- a/web/app/components/datasets/documents/create-from-pipeline/data-source/local-file/components/file-list-item.tsx +++ b/web/app/components/datasets/documents/create-from-pipeline/data-source/local-file/components/file-list-item.tsx @@ -1,10 +1,10 @@ import type { CustomFile as File, FileItem } from '@/models/datasets' import { RiDeleteBinLine, RiErrorWarningFill } from '@remixicon/react' -import dynamic from 'next/dynamic' import { useMemo } from 'react' import DocumentFileIcon from '@/app/components/datasets/common/document-file-icon' import { getFileType } from '@/app/components/datasets/common/image-uploader/utils' import useTheme from '@/hooks/use-theme' +import dynamic from '@/next/dynamic' import { Theme } from '@/types/app' import { cn } from '@/utils/classnames' import { formatFileSize } from '@/utils/format' diff --git a/web/app/components/devtools/react-grab/loader.tsx b/web/app/components/devtools/react-grab/loader.tsx index 3a1ecc6be8ea19..4ee9ad1236f827 100644 --- a/web/app/components/devtools/react-grab/loader.tsx +++ b/web/app/components/devtools/react-grab/loader.tsx @@ -1,5 +1,5 @@ -import Script from 'next/script' import { IS_DEV } from '@/config' +import Script from '@/next/script' export function ReactGrabLoader() { if (!IS_DEV) diff --git a/web/app/components/devtools/react-scan/loader.tsx b/web/app/components/devtools/react-scan/loader.tsx index a5956d782593a4..8e933c2b24dd43 100644 --- a/web/app/components/devtools/react-scan/loader.tsx +++ b/web/app/components/devtools/react-scan/loader.tsx @@ -1,5 +1,5 @@ -import Script from 'next/script' import { IS_DEV } from '@/config' +import Script from '@/next/script' export function ReactScanLoader() { if (!IS_DEV) diff --git a/web/app/components/rag-pipeline/components/panel/index.tsx b/web/app/components/rag-pipeline/components/panel/index.tsx index e39b62eb49ee71..74cdd7034d7678 100644 --- a/web/app/components/rag-pipeline/components/panel/index.tsx +++ b/web/app/components/rag-pipeline/components/panel/index.tsx @@ -1,11 +1,11 @@ import type { PanelProps } from '@/app/components/workflow/panel' -import dynamic from 'next/dynamic' import { memo, useMemo, } from 'react' import Panel from '@/app/components/workflow/panel' import { useStore } from '@/app/components/workflow/store' +import dynamic from '@/next/dynamic' const Record = dynamic(() => import('@/app/components/workflow/panel/record'), { ssr: false, diff --git a/web/app/components/workflow-app/components/workflow-children.tsx b/web/app/components/workflow-app/components/workflow-children.tsx index 0fbb399dd7e2b7..2e65b5963dcf5c 100644 --- a/web/app/components/workflow-app/components/workflow-children.tsx +++ b/web/app/components/workflow-app/components/workflow-children.tsx @@ -3,7 +3,6 @@ import type { TriggerDefaultValue, } from '@/app/components/workflow/block-selector/types' import type { EnvironmentVariable } from '@/app/components/workflow/types' -import dynamic from 'next/dynamic' import { memo, useCallback, @@ -21,6 +20,7 @@ import { useStore } from '@/app/components/workflow/store' import { BlockEnum } from '@/app/components/workflow/types' import { generateNewNode } from '@/app/components/workflow/utils' import { useEventEmitterContextContext } from '@/context/event-emitter' +import dynamic from '@/next/dynamic' import PluginDependency from '../../workflow/plugin-dependency' import { useAvailableNodesMetaData } from '../hooks' import { useAutoOnboarding } from '../hooks/use-auto-onboarding' diff --git a/web/app/components/workflow-app/components/workflow-panel.tsx b/web/app/components/workflow-app/components/workflow-panel.tsx index a1ed289f947439..7f70c53e2e84d9 100644 --- a/web/app/components/workflow-app/components/workflow-panel.tsx +++ b/web/app/components/workflow-app/components/workflow-panel.tsx @@ -1,5 +1,4 @@ import type { PanelProps } from '@/app/components/workflow/panel' -import dynamic from 'next/dynamic' import { memo, useMemo, @@ -8,6 +7,7 @@ import { useShallow } from 'zustand/react/shallow' import { useStore as useAppStore } from '@/app/components/app/store' import Panel from '@/app/components/workflow/panel' import { useStore } from '@/app/components/workflow/store' +import dynamic from '@/next/dynamic' import { useIsChatMode, } from '../hooks' diff --git a/web/app/components/workflow/header/index.tsx b/web/app/components/workflow/header/index.tsx index 0590c016f2b193..bf7479b19800a6 100644 --- a/web/app/components/workflow/header/index.tsx +++ b/web/app/components/workflow/header/index.tsx @@ -1,8 +1,8 @@ import type { HeaderInNormalProps } from './header-in-normal' import type { HeaderInRestoringProps } from './header-in-restoring' import type { HeaderInHistoryProps } from './header-in-view-history' -import dynamic from 'next/dynamic' import { usePathname } from 'next/navigation' +import dynamic from '@/next/dynamic' import { useWorkflowMode, } from '../hooks' diff --git a/web/app/components/workflow/index.tsx b/web/app/components/workflow/index.tsx index 087368029ff870..014193bc5c50d0 100644 --- a/web/app/components/workflow/index.tsx +++ b/web/app/components/workflow/index.tsx @@ -15,7 +15,6 @@ import { } from 'ahooks' import { isEqual } from 'es-toolkit/predicate' import { setAutoFreeze } from 'immer' -import dynamic from 'next/dynamic' import { memo, useCallback, @@ -37,6 +36,7 @@ import ReactFlow, { } from 'reactflow' import { IS_DEV } from '@/config' import { useEventEmitterContextContext } from '@/context/event-emitter' +import dynamic from '@/next/dynamic' import { useAllBuiltInTools, useAllCustomTools, diff --git a/web/app/components/workflow/panel/index.tsx b/web/app/components/workflow/panel/index.tsx index 88ada8b11ecf76..739b10327c9b06 100644 --- a/web/app/components/workflow/panel/index.tsx +++ b/web/app/components/workflow/panel/index.tsx @@ -1,9 +1,9 @@ import type { FC } from 'react' import type { VersionHistoryPanelProps } from '@/app/components/workflow/panel/version-history-panel' -import dynamic from 'next/dynamic' import { memo, useCallback, useEffect, useRef } from 'react' import { useStore as useReactflow } from 'reactflow' import { useShallow } from 'zustand/react/shallow' +import dynamic from '@/next/dynamic' import { cn } from '@/utils/classnames' import { Panel as NodePanel } from '../nodes' import { useStore } from '../store' diff --git a/web/app/layout.tsx b/web/app/layout.tsx index 138d1f7dae8248..be51c76f2e10fb 100644 --- a/web/app/layout.tsx +++ b/web/app/layout.tsx @@ -1,4 +1,4 @@ -import type { Viewport } from 'next' +import type { Viewport } from '@/next' import { Agentation } from 'agentation' import { Provider as JotaiProvider } from 'jotai/react' import { ThemeProvider } from 'next-themes' diff --git a/web/app/repos/[owner]/[repo]/releases/route.ts b/web/app/repos/[owner]/[repo]/releases/route.ts index cc62e9d86c208b..1ae8a5327f0cb4 100644 --- a/web/app/repos/[owner]/[repo]/releases/route.ts +++ b/web/app/repos/[owner]/[repo]/releases/route.ts @@ -1,8 +1,8 @@ -import type { NextRequest } from 'next/server' +import type { NextRequest } from '@/next/server' import { Octokit } from '@octokit/core' import { RequestError } from '@octokit/request-error' -import { NextResponse } from 'next/server' import { GITHUB_ACCESS_TOKEN } from '@/config' +import { NextResponse } from '@/next/server' type Params = { owner: string diff --git a/web/app/signin/_header.tsx b/web/app/signin/_header.tsx index 63be6df6747193..7ebff9f73c9411 100644 --- a/web/app/signin/_header.tsx +++ b/web/app/signin/_header.tsx @@ -1,12 +1,12 @@ 'use client' import type { Locale } from '@/i18n-config' -import dynamic from 'next/dynamic' import Divider from '@/app/components/base/divider' import LocaleSigninSelect from '@/app/components/base/select/locale-signin' import { useGlobalPublicStore } from '@/context/global-public-context' import { useLocale } from '@/context/i18n' import { setLocaleOnClient } from '@/i18n-config' import { languages } from '@/i18n-config/language' +import dynamic from '@/next/dynamic' // Avoid rendering the logo and theme selector on the server const DifyLogo = dynamic(() => import('@/app/components/base/logo/dify-logo'), { diff --git a/web/context/modal-context-provider.tsx b/web/context/modal-context-provider.tsx index 9c86253d6f40d4..5f14729e748566 100644 --- a/web/context/modal-context-provider.tsx +++ b/web/context/modal-context-provider.tsx @@ -11,7 +11,6 @@ import type { InputVar } from '@/app/components/workflow/types' import type { ExpireNoticeModalPayloadProps } from '@/app/education-apply/expire-notice-modal' import type { ApiBasedExtension, ExternalDataTool } from '@/models/common' import type { ModerationConfig, PromptVariable } from '@/models/debug' -import dynamic from 'next/dynamic' import { useCallback, useEffect, useRef, useState } from 'react' import { @@ -27,6 +26,7 @@ import { useAccountSettingModal, usePricingModal, } from '@/hooks/use-query-params' +import dynamic from '@/next/dynamic' import { useTriggerEventsLimitModal } from './hooks/use-trigger-events-limit-modal' import { ModalContext, diff --git a/web/eslint.config.mjs b/web/eslint.config.mjs index 81e3225b3f2be7..4599778eee2441 100644 --- a/web/eslint.config.mjs +++ b/web/eslint.config.mjs @@ -14,6 +14,13 @@ process.env.TAILWIND_MODE ??= 'ESLINT' const disableRuleAutoFix = !(isInEditorEnv() || isInGitHooksOrLintStaged()) +const NEXT_PLATFORM_RESTRICTED_IMPORT_PATHS = [ + { + name: 'next', + message: 'Import Next APIs from @/next instead of next.', + }, +] + const NEXT_PLATFORM_RESTRICTED_IMPORT_PATTERNS = [ { group: ['next/image'], @@ -23,6 +30,22 @@ const NEXT_PLATFORM_RESTRICTED_IMPORT_PATTERNS = [ group: ['next/font', 'next/font/*'], message: 'Do not import next/font. Use the project font styles instead.', }, + { + group: ['next/dynamic'], + message: 'Import Next APIs from @/next/dynamic instead of next/dynamic.', + }, + { + group: ['next/headers'], + message: 'Import Next APIs from @/next/headers instead of next/headers.', + }, + { + group: ['next/script'], + message: 'Import Next APIs from @/next/script instead of next/script.', + }, + { + group: ['next/server'], + message: 'Import Next APIs from @/next/server instead of next/server.', + }, ] const OVERLAY_RESTRICTED_IMPORT_PATTERNS = [ @@ -240,10 +263,12 @@ export default antfu( }, }, { - name: 'dify/no-next-image-or-font', + name: 'dify/no-direct-next-imports', files: [GLOB_TS, GLOB_TSX], + ignores: ['next/**'], rules: { 'no-restricted-imports': ['error', { + paths: NEXT_PLATFORM_RESTRICTED_IMPORT_PATHS, patterns: NEXT_PLATFORM_RESTRICTED_IMPORT_PATTERNS, }], }, @@ -252,11 +277,13 @@ export default antfu( name: 'dify/overlay-migration', files: [GLOB_TS, GLOB_TSX], ignores: [ + 'next/**', ...GLOB_TESTS, ...OVERLAY_MIGRATION_LEGACY_BASE_FILES, ], rules: { 'no-restricted-imports': ['error', { + paths: NEXT_PLATFORM_RESTRICTED_IMPORT_PATHS, patterns: [ ...NEXT_PLATFORM_RESTRICTED_IMPORT_PATTERNS, ...OVERLAY_RESTRICTED_IMPORT_PATTERNS, diff --git a/web/i18n-config/server.ts b/web/i18n-config/server.ts index d9c0501d2d6ea3..e58f4a78de7e1f 100644 --- a/web/i18n-config/server.ts +++ b/web/i18n-config/server.ts @@ -7,9 +7,9 @@ import { camelCase } from 'es-toolkit/string' import { createInstance } from 'i18next' import resourcesToBackend from 'i18next-resources-to-backend' import Negotiator from 'negotiator' -import { cookies, headers } from 'next/headers' import { cache } from 'react' import { initReactI18next } from 'react-i18next/initReactI18next' +import { cookies, headers } from '@/next/headers' import { serverOnlyContext } from '@/utils/server-only-context' import { i18n } from '.' import { namespacesInFileName } from './resources' diff --git a/web/next.config.ts b/web/next.config.ts index 68c51e53e539fd..aa4d9318f47ea4 100644 --- a/web/next.config.ts +++ b/web/next.config.ts @@ -1,4 +1,4 @@ -import type { NextConfig } from 'next' +import type { NextConfig } from '@/next' import createMDX from '@next/mdx' import { codeInspectorPlugin } from 'code-inspector-plugin' import { env } from './env' diff --git a/web/next/dynamic.ts b/web/next/dynamic.ts new file mode 100644 index 00000000000000..6e6008c83f3a6a --- /dev/null +++ b/web/next/dynamic.ts @@ -0,0 +1 @@ +export { default } from 'next/dynamic' diff --git a/web/next/headers.ts b/web/next/headers.ts new file mode 100644 index 00000000000000..6b55f329828d60 --- /dev/null +++ b/web/next/headers.ts @@ -0,0 +1 @@ +export { cookies, headers } from 'next/headers' diff --git a/web/next/index.ts b/web/next/index.ts new file mode 100644 index 00000000000000..01fe7b42a2ef3e --- /dev/null +++ b/web/next/index.ts @@ -0,0 +1 @@ +export type { NextConfig, Viewport } from 'next' diff --git a/web/next/script.ts b/web/next/script.ts new file mode 100644 index 00000000000000..6eda1e8667891e --- /dev/null +++ b/web/next/script.ts @@ -0,0 +1 @@ +export { default } from 'next/script' diff --git a/web/next/server.ts b/web/next/server.ts new file mode 100644 index 00000000000000..037538be96ea71 --- /dev/null +++ b/web/next/server.ts @@ -0,0 +1,2 @@ +export { NextResponse } from 'next/server' +export type { NextRequest } from 'next/server' diff --git a/web/proxy.ts b/web/proxy.ts index 6f2373f1a0fdc0..02513d91b92a3b 100644 --- a/web/proxy.ts +++ b/web/proxy.ts @@ -1,7 +1,7 @@ -import type { NextRequest } from 'next/server' +import type { NextRequest } from '@/next/server' import { Buffer } from 'node:buffer' -import { NextResponse } from 'next/server' import { env } from '@/env' +import { NextResponse } from '@/next/server' const NECESSARY_DOMAIN = '*.sentry.io http://localhost:* http://127.0.0.1:* https://analytics.google.com googletagmanager.com *.googletagmanager.com https://www.google-analytics.com https://api.github.com https://api2.amplitude.com *.amplitude.com'