Hi all. Is it possible to load GoodData UI element...
# gooddata-ui
k
Hi all. Is it possible to load GoodData UI elements in NextJS when using the
edge
runtime inside a dynamic route? We are using NextJS on Cloudflare Pages and everything works great until we tried to render GoodData UI elements within a dynamic route. Then we get an error like the following:
Copy code
./node_modules/@gooddata/sdk-ui-ext/esm/insightView/InsightRenderer.js
Attempted import error: 'render' is not exported from 'react-dom'
m
Hi Kyle, I will check this with our engineers. Could you please share the contents of your package.json file in the meantime?
k
Copy code
{
  "name": "mini-outburst",
  "version": "0.1.0",
  "private": true,
  "scripts": {
    "dev": "next dev -H 0.0.0.0",
    "build": "next build",
    "start": "next start",
    "lint": "next lint",
    "pages:build": "npx @cloudflare/next-on-pages",
    "preview": "npm run pages:build && wrangler pages dev .vercel/output/static",
    "deploy": "npm run pages:build && wrangler pages deploy .vercel/output/static",
    "db:list": "npx wrangler d1 migrations list mini-outburst --local",
    "db:generate": "drizzle-kit generate:sqlite --schema=src/app/schema.ts",
    "db:up": "drizzle-kit up:sqlite --schema=src/app/schema.ts",
    "db:migrate": "npx wrangler d1 migrations apply mini-outburst --local",
    "db:list:prod": "npx wrangler d1 migrations list mini-outburst-prod --remote",
    "db:migrate:prod": "npx wrangler d1 migrations apply mini-outburst-prod --remote",
    "debug": "NODE_OPTIONS='--inspect' next dev",
    "tail": "wrangler pages deployment tail --project-name mini-outburst"
  },
  "dependencies": {
    "@auth0/auth0-react": "^2.2.4",
    "@gooddata/api-client-tiger": "^10.0.0",
    "@gooddata/sdk-backend-tiger": "^10.0.0",
    "@gooddata/sdk-ui-all": "^10.0.0",
    "@headlessui/react": "^2.0.4",
    "@heroicons/react": "^2.1.3",
    "clsx": "^2.1.1",
    "drizzle-orm": "^0.29.4",
    "framer-motion": "^11.2.10",
    "graphql-request": "^7.0.1",
    "jose": "^5.2.4",
    "next": "^14.2.3",
    "react": "^18.2.0",
    "react-beautiful-dnd": "^13.1.1",
    "react-dom": "^18.2.0",
    "styled-components": "^6.1.11",
    "swr": "^2.2.5"
  },
  "devDependencies": {
    "@cloudflare/next-on-pages": "^1.9.0",
    "@cloudflare/workers-types": "^4.20240208.0",
    "@gooddata/catalog-export": "^10.0.0",
    "@types/node": "^18.17.0",
    "@types/react": "^18.2.0",
    "@types/react-beautiful-dnd": "^13.1.8",
    "@types/react-dom": "^18.2.1",
    "autoprefixer": "^10.0.1",
    "drizzle-kit": "^0.20.14",
    "eslint": "^8",
    "eslint-config-next": "14.1.0",
    "eslint-plugin-next-on-pages": "^1.9.0",
    "postcss": "^8",
    "tailwindcss": "^3.4.4",
    "typescript": "^5",
    "vercel": "^33.5.1",
    "wrangler": "^3.28.4"
  }
}
🙌 1
appreciate it!
i've tried numerous different methods to try and get around this but i feel like i'm spinning my wheels now a bit
r
Hi Kyle, Radek from L2 here - this issue has been escalated to L2 and we've been trying to figure this out as well. The error, strangely enough, sounds a lot like what would happen if you were using an older (and unsupported) React version, but 18.2. should be fine.. Could you share the imports and the bit of code from the very root of your app, where
createRoot
is being called? Previously, in v9, we had a workaround to prevent legacy methods being called:
Copy code
import { createRoot } from "react-dom/client";
import { provideCreateRoot } from '@gooddata/sdk-ui-ext';

provideCreateRoot(createRoot);
This shouldn't be relevant anymore, but I'm a big fan of triple-checking 🙂
k
Hi @Radek Novacek, thats whats a bit confusing me to because we are using Nextjs 14+ which doesn't call
createRoot
anywhere either
😅 1
Copy code
'use client';

import type { Metadata } from "next";
import { Inter } from "next/font/google";
import "./globals.css";
import { Auth0Provider } from '@auth0/auth0-react';
import { ThemeProvider as GoodDataThemeProvider } from "@gooddata/sdk-ui-theme-provider";
import { ThemeProvider } from 'styled-components';
import { theme } from '@/styles/theme';
import { customTheme } from '@/styles/goodDataTheme';
import { AuthTokenProvider } from "@/providers/AuthTokenProvider";
import { ApplicationLayout } from "./application-layout";
import { PublicLayout } from "./public-layout";
import { usePathname } from 'next/navigation'

const inter = Inter({ subsets: ["latin"] });

export default function RootLayout({
  children,
}: Readonly<{
  children: React.ReactNode;
}>) {

  const isViewerRoute = usePathname().startsWith('/viewer');

  return (
    <ThemeProvider theme={theme}>
      <GoodDataThemeProvider theme={customTheme}>
        <Auth0Provider
          domain={process.env.NEXT_PUBLIC_AUTH0_ISSUER_DOMAIN as string}
          clientId={process.env.NEXT_PUBLIC_AUTH0_CLIENT_ID as string}
          authorizationParams={{
            redirect_uri: process.env.NEXT_PUBLIC_API_BASE_URL as string,
            audience: "<https://outburstdata.com/api>"
          }}
          cacheLocation="localstorage"
        >
          <AuthTokenProvider>
            <html 
              lang="en"
              className="text-outburst-text antialiased lg:bg-outburst-bg dark:bg-outburst-bg dark:text-outburst-text dark:lg:bg-outburst-bg"
            >
              <head>
                <link rel="icon" href="<https://imagedelivery.net/DzHG7ZU0tz6F1ZKEddmHuw/cdb993d0-7e8f-4d4f-d97d-b0a5e89aa100/public>" />
                <link rel="apple-touch-icon" href="<https://imagedelivery.net/DzHG7ZU0tz6F1ZKEddmHuw/1f4430c9-cad4-4210-e777-71178a3fcb00/public>" />
                <title>Outburst</title>
              </head>
              <body className={inter.className}>
                {isViewerRoute ? <PublicLayout>{children}</PublicLayout> : <ApplicationLayout>{children}</ApplicationLayout>}
              </body>
            </html>
          </AuthTokenProvider>
        </Auth0Provider>
      </GoodDataThemeProvider>
      </ThemeProvider>
  );
}
this is our main layout
r
Hmm, unfortunately my NextJS skills are somewhat limited, since GD.UI doesn't natively support Next.JS 😅 Can you double-check your setup against the integration guide we published just to make sure the basics are correct? Realistically, if everything is set up properly, and you're not trying to include the use of SSR anywhere (since that's not supported at all), then we can at the very least be sure that the basics aren't causing issues here.
k
Sounds good, I'll go through that guide again and see. I think its something with Edge and Dynamic Routes where it sort of acts like SSR even if you define that it isn't
🤞 1
So I went through the guide, and I noticed that once I added the
InsightView
component to a page I started to get the following error. I attached the stack trace too
Copy code
app-index.js:33 Warning: ReactDOM.render is no longer supported in React 18. Use createRoot instead. Until you switch to the new API, your app will behave as if it's running React 17. Learn more: <https://reactjs.org/link/switch-to-createroot>
r
Yeah, that would suggest my hunch was somewhat correct - looks like
InsightView
is trying to use
render
still as a way of also being compatible with React version pre-18, however this shouldn't prevent the whole app from running. The workaround should be the same as above, aka actually importing and using
createRoot
at the root of the app.. but I'm not entirely sure where this would go for a Next.JS implementation 😅
k
i tried a bunch of different methods and just couldn't get it to work. so i built a small endpoint that does not use Edge in NextJS that accepts an
insightId
and then I just render that endpoint as an iframe from within NextJS views that are using dynamic routes at the edge. it worked, but feels like a hack
r
So that would basically confirm that GD.UI really doesn't want to run within the Edge environment, this is unfortunate but then again even Next.JS itself isn't supported out-of-the-box, I'm happy that you found a workaround to this Kyle!