From b4d28fca543a39cd7fb2fe94e86d697c8d38f0c4 Mon Sep 17 00:00:00 2001 From: Jingyi-Dify Date: Fri, 15 May 2026 18:56:21 -0700 Subject: [PATCH] fix(web): polish integration page titles --- web/app/(commonLayout)/integrations/layout.tsx | 12 ++++++++++++ web/app/(commonLayout)/page.tsx | 7 +++++++ .../plugins/plugin-page/__tests__/index.spec.tsx | 15 +++++++++++++++ web/app/components/plugins/plugin-page/index.tsx | 4 +++- .../__tests__/custom-create-card.spec.tsx | 2 +- .../tools/provider/custom-create-card.tsx | 9 ++++----- 6 files changed, 42 insertions(+), 7 deletions(-) create mode 100644 web/app/(commonLayout)/integrations/layout.tsx diff --git a/web/app/(commonLayout)/integrations/layout.tsx b/web/app/(commonLayout)/integrations/layout.tsx new file mode 100644 index 0000000000..a6cd0ad11e --- /dev/null +++ b/web/app/(commonLayout)/integrations/layout.tsx @@ -0,0 +1,12 @@ +'use client' + +import type { PropsWithChildren } from 'react' +import { useTranslation } from 'react-i18next' +import useDocumentTitle from '@/hooks/use-document-title' + +export default function IntegrationsLayout({ children }: PropsWithChildren) { + const { t } = useTranslation() + useDocumentTitle(t('mainNav.integrations', { ns: 'common' })) + + return children +} diff --git a/web/app/(commonLayout)/page.tsx b/web/app/(commonLayout)/page.tsx index 0cc61f1131..7242b21b36 100644 --- a/web/app/(commonLayout)/page.tsx +++ b/web/app/(commonLayout)/page.tsx @@ -1,7 +1,14 @@ +'use client' + import * as React from 'react' +import { useTranslation } from 'react-i18next' import AppList from '@/app/components/explore/app-list' +import useDocumentTitle from '@/hooks/use-document-title' const Home = () => { + const { t } = useTranslation() + useDocumentTitle(t('mainNav.home', { ns: 'common' })) + return } diff --git a/web/app/components/plugins/plugin-page/__tests__/index.spec.tsx b/web/app/components/plugins/plugin-page/__tests__/index.spec.tsx index 59d041f50c..a6ef8b11dd 100644 --- a/web/app/components/plugins/plugin-page/__tests__/index.spec.tsx +++ b/web/app/components/plugins/plugin-page/__tests__/index.spec.tsx @@ -5,6 +5,7 @@ import { useQueryState } from 'nuqs' import { beforeEach, describe, expect, it, vi } from 'vitest' import { renderWithSystemFeatures } from '@/__tests__/utils/mock-system-features' +import useDocumentTitle from '@/hooks/use-document-title' import { usePluginInstallation } from '@/hooks/use-query-params' // Import mocked modules for assertions import { fetchBundleInfoFromMarketPlace, fetchManifestFromMarketPlace } from '@/service/plugins' @@ -184,6 +185,20 @@ describe('PluginPage Component', () => { expect(screen.getByText(/requestAPlugin/i)).toBeInTheDocument() }) + it('should use plugins as document title on plugins tab', () => { + vi.mocked(useQueryState).mockReturnValue(['plugins', vi.fn()]) + + render() + expect(useDocumentTitle).toHaveBeenCalledWith('plugin.metadata.title') + }) + + it('should use marketplace as document title when exploring marketplace', () => { + vi.mocked(useQueryState).mockReturnValue(['discover', vi.fn()]) + + render() + expect(useDocumentTitle).toHaveBeenCalledWith('common.mainNav.marketplace') + }) + it('should render TabSlider', () => { render() // TabSlider renders tab options diff --git a/web/app/components/plugins/plugin-page/index.tsx b/web/app/components/plugins/plugin-page/index.tsx index acd25836ab..427cf997a3 100644 --- a/web/app/components/plugins/plugin-page/index.tsx +++ b/web/app/components/plugins/plugin-page/index.tsx @@ -57,7 +57,6 @@ const PluginPage = ({ }: PluginPageProps) => { const { t } = useTranslation() const docLink = useDocLink() - useDocumentTitle(t('metadata.title', { ns: 'plugin' })) // Use nuqs hook for installation state const [{ packageId, bundleInfo }, setInstallState] = usePluginInstallation() @@ -132,6 +131,9 @@ const PluginPage = ({ const values = Object.values(PLUGIN_TYPE_SEARCH_MAP) return activeTab === PLUGIN_PAGE_TABS_MAP.marketplace || values.includes(activeTab) }, [activeTab]) + useDocumentTitle(isExploringMarketplace + ? t('mainNav.marketplace', { ns: 'common' }) + : t('metadata.title', { ns: 'plugin' })) const handleFileChange = (file: File | null) => { if (!file || !file.name.endsWith('.difypkg')) { diff --git a/web/app/components/tools/provider/__tests__/custom-create-card.spec.tsx b/web/app/components/tools/provider/__tests__/custom-create-card.spec.tsx index d241bc8e96..c83af11761 100644 --- a/web/app/components/tools/provider/__tests__/custom-create-card.spec.tsx +++ b/web/app/components/tools/provider/__tests__/custom-create-card.spec.tsx @@ -136,7 +136,7 @@ describe('CustomCreateCard', () => { render() const docLink = screen.getByText('tools.swaggerAPIAsToolTip').closest('a') - expect(docLink).toHaveAttribute('href', 'https://docs.dify.ai/en/use-dify/nodes/tools') + expect(docLink).toHaveAttribute('href', 'https://docs.dify.ai/en/use-dify/workspace/tools#custom-tool') expect(docLink).toHaveAttribute('target', '_blank') expect(docLink).toHaveAttribute('rel', 'noopener noreferrer') }) diff --git a/web/app/components/tools/provider/custom-create-card.tsx b/web/app/components/tools/provider/custom-create-card.tsx index fb9d870b76..f44b130711 100644 --- a/web/app/components/tools/provider/custom-create-card.tsx +++ b/web/app/components/tools/provider/custom-create-card.tsx @@ -1,24 +1,23 @@ 'use client' import type { CustomCollectionBackend } from '../types' import { toast } from '@langgenius/dify-ui/toast' -import { useMemo, useState } from 'react' +import { useState } from 'react' import { useTranslation } from 'react-i18next' import EditCustomToolModal from '@/app/components/tools/edit-custom-collection-modal' import { useAppContext } from '@/context/app-context' -import { useDocLink } from '@/context/i18n' import { createCustomCollection } from '@/service/tools' import CreateEntryCard from './create-entry-card' +const CUSTOM_TOOL_DOC_URL = 'https://docs.dify.ai/en/use-dify/workspace/tools#custom-tool' + type Props = { onRefreshData: () => void } const Contribute = ({ onRefreshData }: Props) => { const { t } = useTranslation() - const docLink = useDocLink() const { isCurrentWorkspaceManager } = useAppContext() - const linkUrl = useMemo(() => docLink('/use-dify/nodes/tools'), [docLink]) const [isShowEditCollectionToolModal, setIsShowEditCustomCollectionModal] = useState(false) const doCreateCustomToolCollection = async (data: CustomCollectionBackend) => { await createCustomCollection(data) @@ -33,7 +32,7 @@ const Contribute = ({ onRefreshData }: Props) => { setIsShowEditCustomCollectionModal(true)} /> )}