1

I am trying to use Archilogic embed module to show 3d floorplan in my next.js project.

I am trying below code and it says : TypeError: ArchilogicEmbed is not a constructor

import React, { useEffect } from "react";
import dynamic from "next/dynamic";

//import ArchilogicEmbed from "@archilogic/embed-api";

const Archilogic = () => import("@archilogic/embed-api");
const ArchilogicEmbed = dynamic(Archilogic, {
  ssr: false,
});



export default function Dashboard() {
  useEffect(() => {
    async function demo() {
      
      const embedEl = document.getElementById('mapid')
       const embedEl = document.getElementById("mapid");
      const viewer = ArchilogicEmbed(embedEl, {
        transparentBackground: true,
        //presentationMode: PresentationMode.jumpToCameraDefault,
        minimap: false,
        showTitle: false,
        showLogo: false,
        lowResTexturesOnly: false, // prevent hi-res textures from loading, gives a loading-time performance boost at the cost of visual quality
        bookmarksActive: false, // control whether the bookmarks menu should be open or closed
        uiButtons: {
          birdMode: false,
          personMode: false,
          fullscreen: false,
          bookmarkStrip: false,
          share: false,
          help: false,
          presentation: false,
          exportImage: false,
        },
      });

      // await for the viewer embed to be ready
      await viewer.viewerReadyPromise.catch((err) =>
        console.error("viewer couldnt be initialized", err)
      );

      const demoSceneId = <sceneId>;
      const publishableToken = <token>;
      const tokenOptions = { publishableToken };
      await viewer.loadScene(demoSceneId, tokenOptions).catch((err) => {
        // scene couldn't be loaded - it may be private or the ID couldn't be found
        console.error("There was an error loading the scene:", err);
      });
    }

    demo();
  }, []);

}

How do I use ArchilogicEmbed with Next.js?

Here is the link I am following. The example on this link shows ArchilogicEmbed as constructor to initialize viewer and then show it on the page.

Here is codesandbox example from Archilogic.

juliomalves
  • 42,130
  • 20
  • 150
  • 146
newdeveloper
  • 1,401
  • 3
  • 17
  • 43

2 Answers2

1

next/dynamic is used to dynamically import React components. To dynamically import regular JavaScript libraries you can simply use ES2020 dynamic import().

You also need to rename your publishableToken option to publishableAccessToken, as that's the expected syntax.

import React, { useEffect } from "react";

export default function Dashboard() {
    useEffect(() => {
        async function demo() {
            // Dynamically importing `@archilogic/embed-api`
            const ArchilogicEmbed = (await import("@archilogic/embed-api")).default;
            // Target the `demoId` element
            const embedEl = document.getElementById("demoId");
            const viewer = new ArchilogicEmbed(embedEl, {
                // Your options here
            });

            await viewer.viewerReadyPromise.catch((err) =>
                console.error("viewer couldn't be initialized", err)
            );

            const publishableAccessToken = "<your-token>"; // Replace with your token
            const sceneId = "<your-sceneId>"; // Replace with your scene ID
            await viewer
                .loadScene(sceneId, { publishableAccessToken })
                .catch((err) => {
                    console.error("There was an error loading the scene:", err);
                });
        }

        demo();
    }, []);

    return <div id="demoId"></div>;
}
juliomalves
  • 42,130
  • 20
  • 150
  • 146
  • I am just trying to make production build and it fails with an error " window is not defined".. local build works fine. what could be the reason now? thanks for your answer – newdeveloper May 30 '21 at 22:59
  • Error : > Build error occurred ReferenceError: window is not defined at Object. (/Users/.../Documents/.../node_modules/@archilogic/embed-api/dist/embed.js:1:844) – newdeveloper May 30 '21 at 23:00
  • Are you trying to use `@archilogic/embed-api` anywhere outside `useEffect`? – juliomalves May 30 '21 at 23:37
  • Yes on the other page where I use it as usual import. And I dynamic import that page to the actually page when using it. Do you think I should dynamic import the actual one as well ? – newdeveloper May 30 '21 at 23:45
1

I was able to solve it using dynamic import, a slightly different method than what juliomalves suggested here.

I made another file with regular import, but calling it dynamically on the client side. as below:

import React, { useEffect } from "react";
import dynamic from "next/dynamic";

export default function FloorPlan3D() {
  const Map3D = dynamic(() => import("./floorplan"), {
    loading: () => <p>A map is loading</p>,
    ssr: false, // This line is important. It's what prevents server-side render
  });

  return <Map3D />;
}
newdeveloper
  • 1,401
  • 3
  • 17
  • 43
  • If you use this approach make sure to move the `dynamic(...)` call [outside the function, to the top level](https://nextjs.org/docs/advanced-features/dynamic-import#basic-usage) of that file. – juliomalves May 31 '21 at 10:22