fix(web): render marketplace Creator Center from a client module

home-header.tsx is a server component on the standalone marketplace
homepage, where calling buttonVariants() from the client-marked
dify-ui button module crashes SSR with a 500. Extract the Creator
Center link into its own 'use client' file, mirroring home-guide.tsx.

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
CodingOnStar 2026-08-16 11:35:18 +08:00
parent 618f2b8e00
commit 3087b45017
2 changed files with 55 additions and 48 deletions

View File

@ -0,0 +1,51 @@
'use client'
import { buttonVariants } from '@langgenius/dify-ui/button'
import { cn } from '@langgenius/dify-ui/cn'
import { useTranslation } from '#i18n'
import { MARKETPLACE_URL_PREFIX } from '@/config'
import Link from '@/next/link'
const PUBLIC_CREATOR_CENTER_URL = 'https://creators.dify.ai/'
const getCreatorCenterUrl = (marketplaceUrlPrefix: string) => {
if (!marketplaceUrlPrefix) return PUBLIC_CREATOR_CENTER_URL
try {
const marketplaceUrl = new URL(marketplaceUrlPrefix)
const [service, ...domain] = marketplaceUrl.hostname.split('.')
if (!service?.startsWith('marketplace') || domain.length === 0) return PUBLIC_CREATOR_CENTER_URL
marketplaceUrl.hostname = [service.replace(/^marketplace/, 'creators'), ...domain].join('.')
marketplaceUrl.pathname = '/'
marketplaceUrl.search = ''
marketplaceUrl.hash = ''
return marketplaceUrl.toString()
} catch {
return PUBLIC_CREATOR_CENTER_URL
}
}
export default function HomeCreatorCenter() {
const { t } = useTranslation('plugin')
const creatorCenterUrl = getCreatorCenterUrl(MARKETPLACE_URL_PREFIX)
const label = t(($) => $['marketplace.home.creatorCenter'])
return (
<Link
href={creatorCenterUrl}
target="_blank"
rel="noopener noreferrer"
// The visible text is hidden below the lg breakpoint, so the link needs
// an explicit accessible name to avoid becoming an icon-only mystery.
aria-label={label}
className={cn(
buttonVariants({ variant: 'ghost' }),
'flex items-center gap-1 px-3 py-2 text-text-tertiary hover:bg-state-base-hover hover:text-text-secondary [html[data-theme=dark]_&]:text-text-primary [html[data-theme=dark]_&]:hover:text-text-primary',
)}
>
<span aria-hidden className="i-ri-user-star-line size-4" />
<span className="hidden system-sm-medium lg:inline">{label}</span>
</Link>
)
}

View File

@ -1,12 +1,12 @@
import type { HomeCatalogTab, HomeCatalogTabLabels } from './home-catalog-tabs'
import { buttonVariants } from '@langgenius/dify-ui/button'
import { cn } from '@langgenius/dify-ui/cn'
import { useTranslation } from '#i18n'
import { MARKETPLACE_URL_PREFIX } from '@/config'
import Link from '@/next/link'
import MarketplaceLogoDark from '@/public/marketplace/dify-marketplace-logo-dark.svg'
import MarketplaceLogo from '@/public/marketplace/dify-marketplace-logo.svg'
import HomeCatalogTabs from './home-catalog-tabs'
// HomeCreatorCenter stays in its own client module: it derives styles via
// buttonVariants(), which cannot be invoked inside this server component.
import HomeCreatorCenter from './home-creator-center'
import HomeGuide from './home-guide'
import { HomeStickyCatalogTabs } from './home-sticky-state-provider'
import styles from './home-sticky.module.css'
@ -19,50 +19,6 @@ type HomeHeaderProps = {
language?: string
}
const PUBLIC_CREATOR_CENTER_URL = 'https://creators.dify.ai/'
const getCreatorCenterUrl = (marketplaceUrlPrefix: string) => {
if (!marketplaceUrlPrefix) return PUBLIC_CREATOR_CENTER_URL
try {
const marketplaceUrl = new URL(marketplaceUrlPrefix)
const [service, ...domain] = marketplaceUrl.hostname.split('.')
if (!service?.startsWith('marketplace') || domain.length === 0) return PUBLIC_CREATOR_CENTER_URL
marketplaceUrl.hostname = [service.replace(/^marketplace/, 'creators'), ...domain].join('.')
marketplaceUrl.pathname = '/'
marketplaceUrl.search = ''
marketplaceUrl.hash = ''
return marketplaceUrl.toString()
} catch {
return PUBLIC_CREATOR_CENTER_URL
}
}
const CreatorCenter = () => {
const { t } = useTranslation('plugin')
const creatorCenterUrl = getCreatorCenterUrl(MARKETPLACE_URL_PREFIX)
const label = t(($) => $['marketplace.home.creatorCenter'])
return (
<Link
href={creatorCenterUrl}
target="_blank"
rel="noopener noreferrer"
// The visible text is hidden below the lg breakpoint, so the link needs
// an explicit accessible name to avoid becoming an icon-only mystery.
aria-label={label}
className={cn(
buttonVariants({ variant: 'ghost' }),
'flex items-center gap-1 px-3 py-2 text-text-tertiary hover:bg-state-base-hover hover:text-text-secondary [html[data-theme=dark]_&]:text-text-primary [html[data-theme=dark]_&]:hover:text-text-primary',
)}
>
<span aria-hidden className="i-ri-user-star-line size-4" />
<span className="hidden system-sm-medium lg:inline">{label}</span>
</Link>
)
}
const HomeHeader = ({
activeTab = 'plugins',
actions,
@ -118,7 +74,7 @@ const HomeHeader = ({
</div>
<div className="flex h-full min-w-0 flex-1 items-center justify-end gap-2.5">
<CreatorCenter />
<HomeCreatorCenter />
<HomeGuide isMarketplacePlatform={isMarketplacePlatform} />
{actions}
</div>