Closed5

Next.js (App router) + Chakra UI で壊れた

KiKiKi-KiKiKiKiKi-KiKi
  • Next.js v14
  • @chakra-ui/react v2.8.2
  • @chakra-ui/next-js v2.2.0

ガイドラインに沿ってセットアップを行った

https://chakra-ui.com/getting-started/nextjs-app-guide

// app/providers.tsx
'use client'

import { ChakraProvider } from '@chakra-ui/react'

export function Providers({ children }: { children: React.ReactNode }) {
  return <ChakraProvider>{children}</ChakraProvider>
}
// app/layout.tsx
export default function RootLayout({
  children,
}: {
  children: React.ReactNode,
}) {
  return (
    <html lang='en'>
      <body>
        <Providers>{children}</Providers>
      </body>
    </html>
  )
}
KiKiKi-KiKiKiKiKi-KiKi

Warning: Extra attributes from the server: data-new-gr-c-s-check-loaded,data-gr-ext-installed

エラーになり何も表示されない

https://stackoverflow.com/questions/75337953/what-causes-nextjs-warning-extra-attributes-from-the-server-data-new-gr-c-s-c

This is usually caused by an extension passing these extra attributes with your code when it is executed on the browser trying to interact with the UI, this creates a mismatch between what was rendered on the server and what is rendered on the client.

Extensions similar to Grammarly, ColorZilla and LanguageTool are therefore the cause of this warning, so you have to find out which one is doing this and then disable/configure it to not run on the ports you usually use for development. This is the straightforward fix for the warining, since it is always recommended to avoid extensions in development.

https://github.com/chakra-ui/chakra-ui/issues/7040#issuecomment-1868859697

Chrome の拡張が HTML を変更するのが原因で dom の差分が出てしまっているのが原因

Grammarly、ColorZilla、LanguageTool といった拡張が原因らしい

<body data-new-gr-c-s-check-loaded="14.1156.0" data-gr-ext-installed="">

Grammarly が原因だった。Grammarly が body タグに付ける data-new-gr-c-s-check-loaded data-gr-ext-installed 属性がエラーの原因。

対策 1. シークレットウィンドウを使う

拡張が無効なシークレットウィンドウならエラーは発生しない

対策 2. suppressHydrationWarning={true} 属性を使う

You can suppress hydration warnings by setting suppressHydrationWarning to true in the opening <body> tag of the RootLayout:
cf. https://stackoverflow.com/questions/75337953/what-causes-nextjs-warning-extra-attributes-from-the-server-data-new-gr-c-s-c

// app/layout.tsx
export default function RootLayout({
  children,
}: {
  children: React.ReactNode,
}) {
  return (
    <html lang='en'>
-    <body>
+    <body suppressHydrationWarning={true}>
        <Providers>{children}</Providers>
      </body>
    </html>
  )
}

必要であれあば <html> タグにも suppressHydrationWarning={true} を付けると良い
これで Warning: Extra attributes from the server: のエラーは出なくなった

KiKiKi-KiKiKiKiKi-KiKi

Chakra Provider があると deck.gl と MapLibre GL を使った地図が真っ白になる

deck.gl + MapLibre + react-map-gl を使って地図を表示させていたが、<ChakraProvider> が親にあると真っ白になってしまう…

地図表示のコンポーネント

  • deck.gl "^8.9.34"
  • maplibre-gl "^4.0.2"
  • react-map-gl "^7.1.7"
// /src/Map.tsx
'use client'
import { FC } from 'react';
import DeckGL from '@deck.gl/react/typed';
import * as maplibregl from 'maplibre-gl';
import { Map } from 'react-map-gl/maplibre';
import 'maplibre-gl/dist/maplibre-gl.css';

const InitialViewState = {
  longitude: 16.62662018,
  latitude: 49.2125578,
  zoom: 4
};

const MapContainer: FC = () => {
  return (
    <div id='map'>
      <DeckGL initialViewState={InitialViewState} controller={true}>
        <Map
          mapLib={maplibregl}
          initialViewState={{
            longitude: 16.62662018,
            latitude: 49.2125578,
            zoom: 3,
          }}
          style={{ width: '100vw', height: '100vh' }}
          mapStyle='https://demotiles.maplibre.org/style.json'
        >
        </Map>
      </DeckGL>
    </div>
  );
};

export { MapContainer as Map };
// app/page.tsx
import { Map } from '@/Map';

export default function Home() {
  return (
    <main>
      <Map />
    </main>
  );
}

特にエラーも表示さず表示されなくなった。

https://maplibre.org/maplibre-gl-js/docs/
https://visgl.github.io/react-map-gl/docs/get-started
https://qiita.com/asahina820/items/5e3212628184da8e8ee6
https://deck.gl/docs/api-reference/mapbox/mapbox-overlay#using-with-react-map-gl
https://deck.gl/docs/get-started/using-with-react#adding-a-base-map

KiKiKi-KiKiKiKiKi-KiKi

ChakraProvider から use client を外しても効果はない

Chakra UI now works with the Next 13 app router without the need to add use client directive.
https://github.com/chakra-ui/chakra-ui/issues/7649#issuecomment-1769503921

https://github.com/chakra-ui/chakra-ui/issues/7649#issuecomment-1769503921
https://zenn.dev/collabostyle/articles/8e8d76d5611f7e

// app/providers.tsx
- 'use client'
- 
import { ChakraProvider } from '@chakra-ui/react'

export function Providers({ children }: { children: React.ReactNode }) {
  return <ChakraProvider>{children}</ChakraProvider>
}

ChakraProvider から use client を取っても地図は表示されないままだった
逆に use client を付けても効果は無かった

KiKiKi-KiKiKiKiKi-KiKi

DeckGL の親の高さが 0 にっていたのが原因

Chakra UI の theme とバッティングしたのか、コンテナの高さが 0 になっていたために canvas の高さも 0 となち地図が表示されなくなっていただけだった

// /src/Map.tsx
import { FC } from 'react';
import DeckGL from '@deck.gl/react/typed';
import * as maplibregl from 'maplibre-gl';
import { Map } from 'react-map-gl/maplibre';
import 'maplibre-gl/dist/maplibre-gl.css';

const InitialViewState = {
  longitude: 16.62662018,
  latitude: 49.2125578,
  zoom: 4
};

const MapContainer: FC = () => {
  return (
-   <div id='map'>
+   <div id='map' style={{ width: '100%', height: '100vh' }}>
      <DeckGL initialViewState={InitialViewState} controller={true}>
        <Map
          mapLib={maplibregl}
          initialViewState={{
            longitude: 16.62662018,
            latitude: 49.2125578,
            zoom: 3,
          }}
          style={{ width: '100vw', height: '100vh' }}
          mapStyle='https://demotiles.maplibre.org/style.json'
        >
        </Map>
      </DeckGL>
    </div>
  );
};

export { MapContainer as Map };

CSS の問題だった。

これで Chakra UI のコンポーネントを 地図上に表示させられるようになった

このスクラップは2ヶ月前にクローズされました