Embedding FlutterFlow app with react - Query parameters doesn't work

16 Views Asked by At

I am trying to embed Flutterflow app in a React app which uses certain query parameters, I am getting errors while trying to render Flutter widgets as React components. Its working fine when there are no query parameters eg. xyz.com/ but doesn't work when its xyz.com?qp=123

This is the exact error i am getting:

ERROR

Exception: The base href has to end with a "/" to work correctly 
Exception: The base href has to end with a "/" to work correctly at Object.f 
(http://localhost:3000/flutter/main.dart.js:4974:19) at Object.ae 
(http://localhost:3000/flutter/main.dart.js:4983:15) at http://localhost:3000/flutter/main.dart.js:9006:20 at aKV.a 
(http://localhost:3000/flutter/main.dart.js:6303:63) at aKV.$2 
(http://localhost:3000/flutter/main.dart.js:40625:14) at Object.R 
(http://localhost:3000/flutter/main.dart.js:6289:10) at Object.aLH 
(http://localhost:3000/flutter/main.dart.js:9033:10) at aLJ.$0 
(http://localhost:3000/flutter/main.dart.js:81607:15) at http://localhost:3000/flutter/main.dart.js:44865:12 at aKV.a 
(http://localhost:3000/flutter/main.dart.js:6303:63)

Note: When I am embedding a normal flutter app using the same method, its working fine but this is happening specifically with flutterflow apps.

How I am trying to embed?

This is my prebuild npm script:

"prebuild": "cd embedding_test && flutter clean && flutter build web --output=../public/flutter && cd -",

I have placed the app created by flutterflow at the root of my react app, then ran this command. The component that reads the main.dart.js and renders the app has the logic as below:

export const FlutterView: React.FC<FlutterViewProps> = memo(
  ({
    assetBase = "",
    src = "main.dart.js",
    onClicksChange,
    onScreenChange,
    onTextChange,
    text,
    screen,
    clicks,
  }) => {
    const flutterState = useRef<any>(null);
    const ref = useRef<HTMLDivElement>(null);

    const onFlutterAppLoaded = (state: any) => {
      flutterState.current = state;
      // listen to state changes
      state.onClicksChanged(onClicksChange);
      state.onTextChanged(onTextChange);
      state.onScreenChanged(onScreenChange);
      // set initial values
      state.setText(text);
      state.setScreen(screen);
      state.setClicks(clicks);
    };

    useEffect(() => {
      const target = ref.current;
      let isRendered = true;
      const initFlutterApp = async () => {
        if (!isRendered) return;
        const engineInitializer = await new Promise<any>((resolve) => {
          _flutter.loader.loadEntrypoint({
            entrypointUrl: src,
            onEntrypointLoaded: resolve,
          });
        });
        if (!isRendered) return;

        const appRunner = await engineInitializer?.initializeEngine({
          hostElement: target,
          assetBase: assetBase,
        });
        if (!isRendered) return;

        await appRunner?.runApp();
      };
      initFlutterApp();

      const eventListener = (event: Event) => {
        let state = (event as CustomEvent).detail;
        onFlutterAppLoaded(state);
      };

      target?.addEventListener("flutter-initialized", eventListener, {
        once: true,
      });

      return () => {
        isRendered = false;
        target?.removeEventListener("flutter-initialized", eventListener);
      };
      // eslint-disable-next-line react-hooks/exhaustive-deps
    }, []);

    useEffect(() => {
      flutterState.current?.setText(text);
    }, [text]);
    useEffect(() => {
      flutterState.current?.setScreen(screen);
    }, [screen]);
    useEffect(() => {
      flutterState.current?.setClicks(clicks);
    }, [clicks]);

    return (
      <div className="flutter-view" ref={ref} style={divStyle}>
        <Box
          sx={{
            display: "flex",
            alignItems: "center",
            justifyContent: "center",
            height: "100%",
          }}
        >
          <CircularProgress />
        </Box>
      </div>
    );
  }
);
0

There are 0 best solutions below