diff --git a/web/app/components/app/create-from-dsl-modal/index.tsx b/web/app/components/app/create-from-dsl-modal/index.tsx
index 4b5ae92c39..2c540e2897 100644
--- a/web/app/components/app/create-from-dsl-modal/index.tsx
+++ b/web/app/components/app/create-from-dsl-modal/index.tsx
@@ -1,5 +1,6 @@
'use client'
+import type { DocPathWithoutLang } from '@/types/doc-paths'
import { useDebounceFn, useKeyPress } from 'ahooks'
import { noop } from 'es-toolkit/function'
import { useRouter } from 'next/navigation'
@@ -15,7 +16,6 @@ import AppsFull from '@/app/components/billing/apps-full-in-dialog'
import { usePluginDependencies } from '@/app/components/workflow/plugin-dependency/hooks'
import { NEED_REFRESH_APP_LIST_KEY } from '@/config'
import { useAppContext } from '@/context/app-context'
-import { appManagementAnchorMap } from '@/context/doc-anchors'
import { useDocLink } from '@/context/i18n'
import { useProviderContext } from '@/context/provider-context'
import {
@@ -47,6 +47,13 @@ export enum CreateFromDSLModalTab {
FROM_URL = 'from-url',
}
+const appManagementLocalizedPathMap = {
+ 'zh-Hans': '/use-dify/workspace/app-management#应用导出和导入' as DocPathWithoutLang,
+ 'zh_Hans': '/use-dify/workspace/app-management#应用导出和导入' as DocPathWithoutLang,
+ 'ja-JP': '/use-dify/workspace/app-management#アプリのエクスポートとインポート' as DocPathWithoutLang,
+ 'ja_JP': '/use-dify/workspace/app-management#アプリのエクスポートとインポート' as DocPathWithoutLang,
+}
+
const CreateFromDSLModal = ({ show, onSuccess, onClose, activeTab = CreateFromDSLModalTab.FROM_FILE, dslUrl = '', droppedFile }: CreateFromDSLModalProps) => {
const { push } = useRouter()
const { t } = useTranslation()
@@ -313,7 +320,7 @@ const CreateFromDSLModal = ({ show, onSuccess, onClose, activeTab = CreateFromDS
diff --git a/web/app/components/workflow/variable-inspect/artifacts-tab.tsx b/web/app/components/workflow/variable-inspect/artifacts-tab.tsx
index f914204b3b..16eae84004 100644
--- a/web/app/components/workflow/variable-inspect/artifacts-tab.tsx
+++ b/web/app/components/workflow/variable-inspect/artifacts-tab.tsx
@@ -9,7 +9,6 @@ import { FileDownload01 } from '@/app/components/base/icons/src/vender/line/file
import Loading from '@/app/components/base/loading'
import ArtifactsTree from '@/app/components/workflow/skill/file-tree/artifacts/artifacts-tree'
import ReadOnlyFilePreview from '@/app/components/workflow/skill/viewer/read-only-file-preview'
-import { fileSystemArtifactsAnchorMap } from '@/context/doc-anchors'
import { useDocLink } from '@/context/i18n'
import { useDownloadSandboxFile, useSandboxFileDownloadUrl, useSandboxFilesTree } from '@/service/use-sandbox-file'
import { cn } from '@/utils/classnames'
@@ -19,6 +18,13 @@ import { WorkflowRunningStatus } from '../types'
import InspectLayout from './inspect-layout'
import SplitPanel from './split-panel'
+const fileSystemArtifactsLocalizedPathMap = {
+ 'zh-Hans': '/use-dify/build/file-system#产物' as DocPathWithoutLang,
+ 'zh_Hans': '/use-dify/build/file-system#产物' as DocPathWithoutLang,
+ 'ja-JP': '/use-dify/build/file-system#アーティファクト' as DocPathWithoutLang,
+ 'ja_JP': '/use-dify/build/file-system#アーティファクト' as DocPathWithoutLang,
+}
+
const ArtifactsEmpty = ({ description }: { description: string }) => {
const { t } = useTranslation('workflow')
const docLink = useDocLink()
@@ -33,7 +39,7 @@ const ArtifactsEmpty = ({ description }: { description: string }) => {
{description}
diff --git a/web/context/doc-anchors.ts b/web/context/doc-anchors.ts
deleted file mode 100644
index 7325025aca..0000000000
--- a/web/context/doc-anchors.ts
+++ /dev/null
@@ -1,15 +0,0 @@
-import type { DocAnchorMap } from './i18n'
-
-export const appManagementAnchorMap = {
- 'zh-Hans': '应用导出和导入',
- 'zh_Hans': '应用导出和导入',
- 'ja-JP': 'アプリのエクスポートとインポート',
- 'ja_JP': 'アプリのエクスポートとインポート',
-} satisfies DocAnchorMap
-
-export const fileSystemArtifactsAnchorMap = {
- 'zh-Hans': '产物',
- 'zh_Hans': '产物',
- 'ja-JP': 'アーティファクト',
- 'ja_JP': 'アーティファクト',
-} satisfies DocAnchorMap
diff --git a/web/context/i18n.spec.ts b/web/context/i18n.spec.ts
index 4bb2d20c19..7fb05b8aed 100644
--- a/web/context/i18n.spec.ts
+++ b/web/context/i18n.spec.ts
@@ -1,4 +1,4 @@
-import type { DocAnchorMap, DocPathMap } from './i18n'
+import type { DocPathMap } from './i18n'
import type { DocPathWithoutLang } from '@/types/doc-paths'
import { useTranslation } from '#i18n'
import { renderHook } from '@testing-library/react'
@@ -103,7 +103,7 @@ describe('useDocLink', () => {
}
const { result } = renderHook(() => useDocLink())
- const url = result.current('/use-dify/getting-started/quick-start' as DocPathWithoutLang, { pathMap })
+ const url = result.current('/use-dify/getting-started/quick-start' as DocPathWithoutLang, pathMap)
expect(url).toBe(`${defaultDocBaseUrl}/zh/use-dify/getting-started/introduction`)
})
@@ -119,7 +119,7 @@ describe('useDocLink', () => {
}
const { result } = renderHook(() => useDocLink())
- const url = result.current('/use-dify/getting-started/quick-start' as DocPathWithoutLang, { pathMap })
+ const url = result.current('/use-dify/getting-started/quick-start' as DocPathWithoutLang, pathMap)
expect(url).toBe(`${defaultDocBaseUrl}/ja/use-dify/getting-started/quick-start`)
})
@@ -234,17 +234,6 @@ describe('useDocLink', () => {
const url = result.current('/use-dify/getting-started/introduction')
expect(url).toBe(`${defaultDocBaseUrl}/zh/use-dify/getting-started/introduction`)
})
-
- it('should preserve anchor while translating API reference path', () => {
- vi.mocked(useTranslation).mockReturnValue({
- i18n: { language: 'zh-Hans' },
- } as ReturnType)
- vi.mocked(getDocLanguage).mockReturnValue('zh')
-
- const { result } = renderHook(() => useDocLink())
- const url = result.current('/api-reference/annotations/create-annotation#request-body')
- expect(url).toBe(`${defaultDocBaseUrl}/api-reference/标注管理/创建标注#request-body`)
- })
})
describe('Edge Cases', () => {
@@ -254,20 +243,22 @@ describe('useDocLink', () => {
expect(url).toBe(`${defaultDocBaseUrl}/en/use-dify/getting-started/introduction#overview`)
})
- it('should support locale-specific anchors via anchorMap', () => {
+ it('should support locale-specific anchors via pathMap', () => {
vi.mocked(useTranslation).mockReturnValue({
i18n: { language: 'zh-Hans' },
} as ReturnType)
vi.mocked(getDocLanguage).mockReturnValue('zh')
- const anchorMap: DocAnchorMap = {
- 'zh-Hans': '应用导出和导入',
- 'ja-JP': 'アプリのエクスポートとインポート',
+ const pathMap: DocPathMap = {
+ 'zh-Hans': '/use-dify/workspace/app-management#应用导出和导入' as DocPathWithoutLang,
+ 'zh_Hans': '/use-dify/workspace/app-management#应用导出和导入' as DocPathWithoutLang,
+ 'ja-JP': '/use-dify/workspace/app-management#アプリのエクスポートとインポート' as DocPathWithoutLang,
+ 'ja_JP': '/use-dify/workspace/app-management#アプリのエクスポートとインポート' as DocPathWithoutLang,
}
const { result } = renderHook(() => useDocLink())
- const url = result.current('/use-dify/workspace/app-management#app-export-and-import', { anchorMap })
- expect(url).toBe(`${defaultDocBaseUrl}/zh/use-dify/workspace/app-management#${encodeURIComponent('应用导出和导入')}`)
+ const url = result.current('/use-dify/workspace/app-management#app-export-and-import', pathMap)
+ expect(url).toBe(`${defaultDocBaseUrl}/zh/use-dify/workspace/app-management#应用导出和导入`)
})
it('should handle multiple calls with same hook instance', () => {
diff --git a/web/context/i18n.ts b/web/context/i18n.ts
index 8b0e89e8fd..6c84d01903 100644
--- a/web/context/i18n.ts
+++ b/web/context/i18n.ts
@@ -1,7 +1,7 @@
import type { Locale } from '@/i18n-config/language'
import type { DocPathWithoutLang } from '@/types/doc-paths'
import { useTranslation } from '#i18n'
-import { useCallback, useMemo } from 'react'
+import { useCallback } from 'react'
import { getDocLanguage, getLanguage, getPricingPageLanguage } from '@/i18n-config/language'
import { apiReferencePathTranslations } from '@/types/doc-paths'
@@ -23,63 +23,29 @@ export const useGetPricingPageLanguage = () => {
export const defaultDocBaseUrl = 'https://docs.bash-is-all-you-need.dify.dev'
export type DocPathMap = Partial>
-export type DocAnchorMap = Partial>
-export type DocLinkOptions = {
- pathMap?: DocPathMap
- anchorMap?: DocAnchorMap
-}
-export type BuildDocLink = (path?: DocPathWithoutLang, options?: DocLinkOptions) => string
-const splitPathWithHash = (path: string) => {
- const [pathname, ...hashParts] = path.split('#')
- return {
- pathname,
- hash: hashParts.join('#'),
- }
-}
-
-const normalizeAnchor = (anchor: string) => {
- const normalizedAnchor = anchor.startsWith('#') ? anchor.slice(1) : anchor
- if (!normalizedAnchor)
- return ''
-
- const isAsciiOnly = Array.from(normalizedAnchor).every(char => char.codePointAt(0)! <= 0x7F)
- if (isAsciiOnly)
- return normalizedAnchor
-
- return encodeURIComponent(normalizedAnchor)
-}
-
-export const useDocLink = (baseUrl?: string): BuildDocLink => {
- const baseDocUrl = useMemo(() => {
- const resolvedBaseUrl = baseUrl || defaultDocBaseUrl
- return resolvedBaseUrl.endsWith('/') ? resolvedBaseUrl.slice(0, -1) : resolvedBaseUrl
- }, [baseUrl])
+export const useDocLink = (baseUrl?: string): ((path?: DocPathWithoutLang, pathMap?: DocPathMap) => string) => {
+ let baseDocUrl = baseUrl || defaultDocBaseUrl
+ baseDocUrl = (baseDocUrl.endsWith('/')) ? baseDocUrl.slice(0, -1) : baseDocUrl
const locale = useLocale()
return useCallback(
- (path?: DocPathWithoutLang, options?: DocLinkOptions): string => {
+ (path?: DocPathWithoutLang, pathMap?: DocPathMap): string => {
const docLanguage = getDocLanguage(locale)
const pathUrl = path || ''
- const { pathMap, anchorMap } = options || {}
- const targetPath = (pathMap) ? pathMap[locale] || pathUrl : pathUrl
- const { pathname: pathWithoutHash, hash: pathAnchor } = splitPathWithHash(targetPath)
- let targetPathWithoutHash = pathWithoutHash
+ let targetPath = (pathMap) ? pathMap[locale] || pathUrl : pathUrl
let languagePrefix = `/${docLanguage}`
- if (targetPathWithoutHash.startsWith('/api-reference/')) {
+ if (targetPath.startsWith('/api-reference/')) {
languagePrefix = ''
if (docLanguage !== 'en') {
- const translatedPath = apiReferencePathTranslations[targetPathWithoutHash]?.[docLanguage]
+ const translatedPath = apiReferencePathTranslations[targetPath]?.[docLanguage]
if (translatedPath) {
- targetPathWithoutHash = translatedPath
+ targetPath = translatedPath
}
}
}
- const anchor = normalizeAnchor(anchorMap?.[locale] || pathAnchor)
- const anchorSuffix = anchor ? `#${anchor}` : ''
-
- return `${baseDocUrl}${languagePrefix}${targetPathWithoutHash}${anchorSuffix}`
+ return `${baseDocUrl}${languagePrefix}${targetPath}`
},
[baseDocUrl, locale],
)