2222 * SOFTWARE.
2323 */
2424
25+ // Populated at runtime by webpack from output.publicPath, e.g. '/',
26+ // '/pr-preview/pr-123/', or '/instructure-design-tokens/pr-preview/pr-5/'.
27+ declare const __webpack_public_path__ : string
28+
2529const MINOR_VERSION_REGEX = / ^ v \d + _ \d + $ /
2630
2731type ParsedUrl = {
28- prPrefix : string
32+ basePrefix : string
2933 minorVersion : string | null
3034 page : string
3135 sectionId : string | undefined
3236}
3337
38+ /**
39+ * Returns the build's deploy base (webpack output.publicPath) with no
40+ * trailing slash. Empty string when served at the domain root.
41+ *
42+ * For PR previews on instructure.design this is '/pr-preview/pr-<n>'.
43+ * For sub-host deployments it can be '/<repo>/pr-preview/pr-<n>'.
44+ */
45+ function getDeployBase ( ) : string {
46+ if ( typeof __webpack_public_path__ === 'string' && __webpack_public_path__ ) {
47+ return __webpack_public_path__ . replace ( / \/ + $ / , '' )
48+ }
49+ return ''
50+ }
51+
3452function parseCurrentUrl ( ) : ParsedUrl {
3553 const { pathname, hash } = window . location
36- const cleanPath = pathname . replace ( / ^ \/ + | \/ + $ / g, '' )
54+
55+ // Strip the deploy base so the rest of the parser can ignore it.
56+ // The PR-preview prefix that the old code sniffed out of the URL is now
57+ // captured in the deploy base itself (webpack's publicPath includes it).
58+ const deployBase = getDeployBase ( )
59+ let rest = pathname
60+ if ( deployBase && rest . startsWith ( deployBase ) ) {
61+ rest = rest . slice ( deployBase . length )
62+ }
63+
64+ const cleanPath = rest . replace ( / ^ \/ + | \/ + $ / g, '' )
3765 const segments = cleanPath . split ( '/' ) . filter ( Boolean )
3866
39- let prPrefix = ''
67+ // In-app namespace prefix (within a single deploy): /latest or empty.
68+ // Versioned routes (/vM_N) and pages follow.
69+ let appPrefix = ''
4070 let idx = 0
4171
42- // Detect PR preview prefix: /pr-preview/pr-123
43- if (
44- segments . length >= 2 &&
45- segments [ 0 ] === 'pr-preview' &&
46- segments [ 1 ] . startsWith ( 'pr-' )
47- ) {
48- prPrefix = `/${ segments [ 0 ] } /${ segments [ 1 ] } `
49- idx = 2
50- }
51-
52- // Detect /latest/ prefix
53- if ( idx === 0 && segments [ idx ] === 'latest' ) {
54- prPrefix = '/latest'
72+ if ( segments [ idx ] === 'latest' ) {
73+ appPrefix = '/latest'
5574 idx ++
5675 }
5776
@@ -71,7 +90,9 @@ function parseCurrentUrl(): ParsedUrl {
7190 sectionId = decodeURI ( hash . replace ( / ^ # + / , '' ) )
7291 }
7392
74- return { prPrefix, minorVersion, page, sectionId }
93+ // basePrefix spans the deploy base + in-app namespace, so buildUrl
94+ // produces correct outbound links under any deploy host.
95+ return { basePrefix : deployBase + appPrefix , minorVersion, page, sectionId }
7596}
7697
7798type BuildUrlOptions = {
@@ -80,13 +101,13 @@ type BuildUrlOptions = {
80101}
81102
82103function buildUrl ( targetPage : string , options ?: BuildUrlOptions ) : string {
83- const { prPrefix } = parseCurrentUrl ( )
104+ const parsed = parseCurrentUrl ( )
84105 const minorVersion =
85106 options ?. minorVersion !== undefined
86107 ? options . minorVersion
87- : parseCurrentUrl ( ) . minorVersion
108+ : parsed . minorVersion
88109
89- let url = prPrefix
110+ let url = parsed . basePrefix
90111
91112 if ( minorVersion ) {
92113 url += `/${ minorVersion } `
@@ -119,11 +140,15 @@ function navigateToVersion(version: string | null): void {
119140}
120141
121142/**
122- * Returns the base path prefix for fetching static assets.
123- * On PR previews this is e.g. `/pr-preview/pr-2425`, otherwise empty string.
143+ * Returns the base path for fetching this build's static assets
144+ * (legacy-icons-data.json, markdown-and-sources-data.json, etc.). These
145+ * always live next to main.js — i.e. at the deploy base, regardless of any
146+ * /latest or /vM_N in-app namespace.
147+ *
148+ * For PR previews this is e.g. `/pr-preview/pr-2425`. Empty at the root.
124149 */
125150function getAssetBasePath ( ) : string {
126- return parseCurrentUrl ( ) . prPrefix
151+ return getDeployBase ( )
127152}
128153
129154export {
0 commit comments