diff --git a/.changeset/dev-local-url-fallback.md b/.changeset/dev-local-url-fallback.md
new file mode 100644
index 00000000000..93c211f23cb
--- /dev/null
+++ b/.changeset/dev-local-url-fallback.md
@@ -0,0 +1,5 @@
+---
+'@shopify/app': patch
+---
+
+Show Local URL in dev info when no App URL is available
diff --git a/packages/app/src/cli/services/dev.ts b/packages/app/src/cli/services/dev.ts
index 63201dca8b4..2798403311b 100644
--- a/packages/app/src/cli/services/dev.ts
+++ b/packages/app/src/cli/services/dev.ts
@@ -439,6 +439,7 @@ async function launchDevProcesses({
appName: config.remoteApp.title,
organizationName: config.commandOptions.organization.businessName,
configPath: config.localApp.configPath,
+ localURL: config.network.proxyUrl,
})
}
diff --git a/packages/app/src/cli/services/dev/ui.tsx b/packages/app/src/cli/services/dev/ui.tsx
index 8477287ff48..4d4a53f8406 100644
--- a/packages/app/src/cli/services/dev/ui.tsx
+++ b/packages/app/src/cli/services/dev/ui.tsx
@@ -21,12 +21,14 @@ export async function renderDev({
appName,
organizationName,
configPath,
+ localURL,
}: DevProps & {
devSessionStatusManager: DevSessionStatusManager
appURL?: string
appName?: string
organizationName?: string
configPath?: string
+ localURL?: string
}) {
if (!terminalSupportsPrompting()) {
await renderDevNonInteractive({processes, app, abortController, developerPreview, shopFqdn})
@@ -41,6 +43,7 @@ export async function renderDev({
appName={appName}
organizationName={organizationName}
configPath={configPath}
+ localURL={localURL}
onAbort={async () => {
await app.developerPlatformClient.devSessionDelete({appId: app.id, shopFqdn})
}}
diff --git a/packages/app/src/cli/services/dev/ui/components/DevSessionUI.test.tsx b/packages/app/src/cli/services/dev/ui/components/DevSessionUI.test.tsx
index 6081f2052d9..06c85d56802 100644
--- a/packages/app/src/cli/services/dev/ui/components/DevSessionUI.test.tsx
+++ b/packages/app/src/cli/services/dev/ui/components/DevSessionUI.test.tsx
@@ -554,6 +554,64 @@ describe('DevSessionUI', () => {
renderInstance.unmount()
})
+ test('hides Local URL in app info when an app URL is available', async () => {
+ // Given
+ const renderInstance = render(
+ ,
+ )
+
+ await waitForInputsToBeReady()
+
+ // When
+ await sendInputAndWait(renderInstance, 10, 'a')
+
+ // Then - only App URL is shown, Local URL is hidden
+ const output = unstyled(renderInstance.lastFrame()!)
+ expect(output).toContain('App URL:')
+ expect(output).toContain('https://my-app.ngrok.io')
+ expect(output).not.toContain('Local URL:')
+ expect(output).not.toContain('http://localhost:3000')
+
+ renderInstance.unmount()
+ })
+
+ test('shows Local URL in app info when no app URL is available', async () => {
+ // Given
+ const renderInstance = render(
+ ,
+ )
+
+ await waitForInputsToBeReady()
+
+ // When
+ await sendInputAndWait(renderInstance, 10, 'a')
+
+ // Then - Local URL is shown in place of App URL
+ const output = unstyled(renderInstance.lastFrame()!)
+ expect(output).toContain('Local URL:')
+ expect(output).toContain('http://localhost:3000')
+ expect(output).not.toContain('App URL:')
+
+ renderInstance.unmount()
+ })
+
test('hides URL list when terminal supports hyperlinks', async () => {
// Given
mocks.terminalSupportsHyperlinks.mockReturnValue(true)
diff --git a/packages/app/src/cli/services/dev/ui/components/DevSessionUI.tsx b/packages/app/src/cli/services/dev/ui/components/DevSessionUI.tsx
index 0b5e53a4d0a..6f99d6ed7b4 100644
--- a/packages/app/src/cli/services/dev/ui/components/DevSessionUI.tsx
+++ b/packages/app/src/cli/services/dev/ui/components/DevSessionUI.tsx
@@ -37,6 +37,7 @@ interface DevSesionUIProps {
appName?: string
organizationName?: string
configPath?: string
+ localURL?: string
onAbort: () => Promise
}
@@ -49,6 +50,7 @@ const DevSessionUI: FunctionComponent = ({
appName,
organizationName,
configPath,
+ localURL,
onAbort,
}) => {
const {isRawModeSupported: canUseShortcuts} = useStdin()
@@ -230,6 +232,7 @@ const DevSessionUI: FunctionComponent = ({
tabularData={[
['App:', appName ?? ''],
['App URL:', appURL ?? ''],
+ ['Local URL:', appURL ? '' : (localURL ?? '')],
['Config:', configPath?.split('/').pop() ?? ''],
['Org:', organizationName ?? ''],
].filter(([, value]) => value)}