Skip to content

Streaming with remix does not work inside iframe #895

Open
@silintzir

Description

Issue summary

Before opening this issue, I have:

  • Upgraded to the latest version of the @shopify packages
    • Affected package and version:
{
    "react-dom": "^18.3.1",
    "react-hook-form": "^7.53.2",
    "express": "^4.21.1",
    "@shopify/admin-api-client": "^1.0.4",
    "@shopify/app-bridge-react": "^4.1.5",
    "@shopify/polaris": "^13.9.1",
    "@shopify/polaris-icons": "^9.3.0",
    "@shopify/shopify-api": "^11.6.0",
    "@shopify/shopify-app-remix": "^3.4.0",
    "@remix-run/dev": "^2.15.0",
    "@remix-run/express": "^2.15.0",
    "@remix-run/node": "^2.15.0",
    "@remix-run/react": "^2.15.0",
    "vite": "^5.4.11"
}
  • Node version: 22.11.0
  • Package manager: [email protected]
  • Operating system: Linux Ubuntu
  • Browsers tested: Chrome,Firefox
  • Tested both with no tunnel used for development but express server running in as https on port 443 and with ngrok that is not know to have any issues with streaming
  • No future flags have been enabled for remix
  • Set { logger: { level: LogSeverity.Debug } } in my configuration
  • Found a reliable way to reproduce the problem that indicates it's a problem with the package
  • Looked for similar issues in this repository
  • Checked that this isn't an issue with a Shopify API

Streaming (defer with Suspense/Await) as described in Remix dev docs is not working on initial page load inside the iframe, while working outside the iframe and on consecutive navigation between pages.

Expected behavior

Page should load with initial page date from loader during the SSR phase, with suspense displaying the fallback message until the promise resolves and streamed data appear on the page as well.

Actual behavior

Page remains blank during initial load waiting for the promise to resolve. Once the promise resolves both ssr and stream data display.

Steps to reproduce the problem

import { defer } from '@remix-run/node';
import { Await, useLoaderData } from '@remix-run/react';
import { Suspense } from 'react';

export const loader = async () => {
  return defer({
    ssr: 'I should display on initial SSR',
    stream: new Promise((res) =>
      setTimeout(() => res('I should be displayed only after promise resolves'), 3000),
    ) as Promise<string>,
  });
};

export default function Tutorial() {
  const { ssr, stream } = useLoaderData<typeof loader>();

  return (
    <div>
      <p>SSR Data: {ssr}</p>
      <Suspense fallback="Loading stream data...">
        <Await resolve={stream} errorElement={<p>Failed to load stream data</p>}>
          {(data) => <p>Stream Data: {data}</p>}
        </Await>
      </Suspense>
    </div>
  );
}

Metadata

Assignees

Labels

No labels
No labels

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions