/
resolve-url.ts
99 lines (84 loc) · 2.88 KB
/
resolve-url.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
import path from '../../../shared/lib/isomorphic/path'
import * as Log from '../../../build/output/log'
function isStringOrURL(icon: any): icon is string | URL {
return typeof icon === 'string' || icon instanceof URL
}
function createLocalMetadataBase() {
return new URL(`http://localhost:${process.env.PORT || 3000}`)
}
// For deployment url for metadata routes, prefer to use the deployment url if possible
// as these routes are unique to the deployments url.
export function getSocialImageFallbackMetadataBase(
metadataBase: URL | null
): URL | null {
const isMetadataBaseMissing = !metadataBase
const defaultMetadataBase = createLocalMetadataBase()
const deploymentUrl =
process.env.VERCEL_URL && new URL(`https://${process.env.VERCEL_URL}`)
let fallbackMetadata
if (process.env.NODE_ENV === 'development') {
fallbackMetadata = defaultMetadataBase
} else {
fallbackMetadata =
process.env.NODE_ENV === 'production' &&
deploymentUrl &&
process.env.VERCEL_ENV === 'preview'
? deploymentUrl
: metadataBase || deploymentUrl || defaultMetadataBase
}
if (isMetadataBaseMissing) {
Log.warnOnce('')
Log.warnOnce(
`metadata.metadataBase is not set for resolving social open graph or twitter images, using "${fallbackMetadata.origin}". See https://nextjs.org/docs/app/api-reference/functions/generate-metadata#metadatabase`
)
}
return fallbackMetadata
}
function resolveUrl(url: null | undefined, metadataBase: URL | null): null
function resolveUrl(url: string | URL, metadataBase: URL | null): URL
function resolveUrl(
url: string | URL | null | undefined,
metadataBase: URL | null
): URL | null
function resolveUrl(
url: string | URL | null | undefined,
metadataBase: URL | null
): URL | null {
if (url instanceof URL) return url
if (!url) return null
try {
// If we can construct a URL instance from url, ignore metadataBase
const parsedUrl = new URL(url)
return parsedUrl
} catch (_) {}
if (!metadataBase) {
metadataBase = createLocalMetadataBase()
}
// Handle relative or absolute paths
const basePath = metadataBase.pathname || ''
const joinedPath = path.join(basePath, url)
return new URL(joinedPath, metadataBase)
}
// Resolve with `pathname` if `url` is a relative path.
function resolveRelativeUrl(url: string | URL, pathname: string): string | URL {
if (typeof url === 'string' && url.startsWith('./')) {
return path.resolve(pathname, url)
}
return url
}
// Resolve `pathname` if `url` is a relative path the compose with `metadataBase`.
function resolveAbsoluteUrlWithPathname(
url: string | URL,
metadataBase: URL | null,
pathname: string
) {
url = resolveRelativeUrl(url, pathname)
const result = metadataBase ? resolveUrl(url, metadataBase) : url
return result.toString()
}
export {
isStringOrURL,
resolveUrl,
resolveRelativeUrl,
resolveAbsoluteUrlWithPathname,
}