mirror of
https://github.com/langgenius/dify.git
synced 2026-07-27 06:58:30 +08:00
fix(web): make marketplace URL builder SSR-safe (#37944)
This commit is contained in:
parent
677ab01806
commit
4cd8b8c733
@ -162,7 +162,7 @@ export default function IntegrationsPage({
|
||||
return
|
||||
}
|
||||
|
||||
window.open(getMarketplaceUrl(marketplaceUrlPath), '_blank', 'noopener,noreferrer')
|
||||
window.open(getMarketplaceUrl(marketplaceUrlPath, undefined, { source: window.location.origin }), '_blank', 'noopener,noreferrer')
|
||||
}
|
||||
const handleSelectSection = (nextSection: IntegrationSection) => {
|
||||
if (onSectionChange) {
|
||||
|
||||
@ -25,7 +25,7 @@ export default function IntegrationsSettingModal({
|
||||
const { t } = useTranslation()
|
||||
const isAgentSource = source === 'agent'
|
||||
const handleSwitchToMarketplace = useCallback((path: string) => {
|
||||
window.open(getMarketplaceUrl(path), '_blank', 'noopener,noreferrer')
|
||||
window.open(getMarketplaceUrl(path, undefined, { source: window.location.origin }), '_blank', 'noopener,noreferrer')
|
||||
}, [])
|
||||
|
||||
return (
|
||||
|
||||
@ -1,3 +1,4 @@
|
||||
import { describe, expect, it, vi } from 'vitest'
|
||||
import { InputVarType } from '@/app/components/workflow/types'
|
||||
import {
|
||||
checkKey,
|
||||
@ -207,6 +208,30 @@ describe('Variable Utilities', () => {
|
||||
expect(url).toContain('category=ai')
|
||||
expect(url).not.toContain('version=')
|
||||
})
|
||||
|
||||
it('should include provided source without double encoding', () => {
|
||||
const url = getMarketplaceUrl('/plugins', { category: 'ai' }, { source: 'https://example.com/app' })
|
||||
expect(url).toContain('source=https%3A%2F%2Fexample.com')
|
||||
expect(url).not.toContain('source=https%253A%252F%252Fexample.com')
|
||||
})
|
||||
|
||||
it('should not access window during server render', () => {
|
||||
const originalWindow = window
|
||||
vi.stubGlobal('window', undefined)
|
||||
|
||||
try {
|
||||
const url = getMarketplaceUrl('/plugins', { category: 'ai' })
|
||||
expect(url).toContain('category=ai')
|
||||
expect(url).not.toContain('source=')
|
||||
}
|
||||
finally {
|
||||
vi.stubGlobal('window', originalWindow)
|
||||
}
|
||||
})
|
||||
|
||||
it('should not append empty query string when no params are available', () => {
|
||||
expect(getMarketplaceUrl('/plugins')).toBe('/plugins')
|
||||
})
|
||||
})
|
||||
|
||||
describe('replaceSpaceWithUnderscoreInVarNameInput', () => {
|
||||
|
||||
@ -132,8 +132,30 @@ export const getVars = (value: string) => {
|
||||
// example: /dify
|
||||
export const basePath = env.NEXT_PUBLIC_BASE_PATH
|
||||
|
||||
export function getMarketplaceUrl(path: string, params?: Record<string, string | undefined>) {
|
||||
const searchParams = new URLSearchParams({ source: encodeURIComponent(window.location.origin) })
|
||||
type MarketplaceUrlOptions = {
|
||||
source?: string
|
||||
}
|
||||
|
||||
const getUrlOrigin = (url?: string) => {
|
||||
if (!url)
|
||||
return undefined
|
||||
|
||||
try {
|
||||
return new URL(url).origin
|
||||
}
|
||||
catch {
|
||||
return undefined
|
||||
}
|
||||
}
|
||||
|
||||
const marketplaceSource = getUrlOrigin(env.NEXT_PUBLIC_WEB_PREFIX)
|
||||
|
||||
export function getMarketplaceUrl(path: string, params?: Record<string, string | undefined>, options?: MarketplaceUrlOptions) {
|
||||
const searchParams = new URLSearchParams()
|
||||
const source = getUrlOrigin(options?.source) ?? marketplaceSource
|
||||
if (source)
|
||||
searchParams.set('source', source)
|
||||
|
||||
if (params) {
|
||||
Object.keys(params).forEach((key) => {
|
||||
const value = params[key]
|
||||
@ -141,7 +163,9 @@ export function getMarketplaceUrl(path: string, params?: Record<string, string |
|
||||
searchParams.append(key, value)
|
||||
})
|
||||
}
|
||||
return `${MARKETPLACE_URL_PREFIX}${path}?${searchParams.toString()}`
|
||||
|
||||
const queryString = searchParams.toString()
|
||||
return queryString ? `${MARKETPLACE_URL_PREFIX}${path}?${queryString}` : `${MARKETPLACE_URL_PREFIX}${path}`
|
||||
}
|
||||
|
||||
export const replaceSpaceWithUnderscoreInVarNameInput = (input: HTMLInputElement) => {
|
||||
|
||||
Loading…
Reference in New Issue
Block a user