diff --git a/packages/core/admin/admin/src/render.ts b/packages/core/admin/admin/src/render.ts index bf7bdf6852..497b7a4cdc 100644 --- a/packages/core/admin/admin/src/render.ts +++ b/packages/core/admin/admin/src/render.ts @@ -3,6 +3,7 @@ import { getFetchClient } from '@strapi/helper-plugin'; import { createRoot } from 'react-dom/client'; import { StrapiApp, StrapiAppConstructorArgs } from './StrapiApp'; +import { createAbsoluteUrl } from './utils/urls'; import type { FeaturesService } from '@strapi/types'; @@ -27,7 +28,7 @@ const renderAdmin = async ( * * To ensure that the backendURL is always set, we use the window.location.origin as a fallback. */ - backendURL: process.env.STRAPI_ADMIN_BACKEND_URL || window.location.origin, + backendURL: createAbsoluteUrl(process.env.STRAPI_ADMIN_BACKEND_URL), isEE: false, telemetryDisabled: process.env.STRAPI_TELEMETRY_DISABLED === 'true' ? true : false, future: { diff --git a/packages/core/admin/admin/src/utils/tests/urls.test.ts b/packages/core/admin/admin/src/utils/tests/urls.test.ts new file mode 100644 index 0000000000..d3e88e5e5e --- /dev/null +++ b/packages/core/admin/admin/src/utils/tests/urls.test.ts @@ -0,0 +1,25 @@ +import { createAbsoluteUrl } from '../urls'; + +describe('urls', () => { + describe('createAbsoluteUrl', () => { + it('should return the url if it is an absolute URL', () => { + expect(createAbsoluteUrl('https://example.com')).toMatchInlineSnapshot( + `"https://example.com"` + ); + }); + + it('should return the window.location.origin if the url is not provided', () => { + expect(createAbsoluteUrl()).toMatchInlineSnapshot(`"http://localhost:1337"`); + }); + + it('should return the window.location.origin prefixed to the provided url if the url is relative', () => { + expect(createAbsoluteUrl('/example')).toMatchInlineSnapshot( + `"http://localhost:1337/example"` + ); + }); + + it('should handle protocol relative URLs', () => { + expect(createAbsoluteUrl('//example.com')).toMatchInlineSnapshot(`"http://example.com/"`); + }); + }); +}); diff --git a/packages/core/admin/admin/src/utils/urls.ts b/packages/core/admin/admin/src/utils/urls.ts new file mode 100644 index 0000000000..e8c6a9a0f3 --- /dev/null +++ b/packages/core/admin/admin/src/utils/urls.ts @@ -0,0 +1,21 @@ +/** + * @description Creates an absolute URL, if there is no URL or it + * is relative, we use the `window.location.origin` as a fallback. + * IF it's an absolute URL, we return it as is. + */ +const createAbsoluteUrl = (url?: string): string => { + if (!url) { + return window.location.origin; + } + if (url.startsWith('/')) { + /** + * This will also manage protocol relative URLs which is fine because + * as we can see from the test, we still get the expected result. + */ + return new URL(url, window.location.origin).toString(); + } else { + return url; + } +}; + +export { createAbsoluteUrl };