Skip to content

Version 2 bug: Hydration mismatch in Next.js due to inline styles on <html> tag Body: #79

@jeesunikim

Description

@jeesunikim

When using stellar-wallets-kit v2 (jsr:2.0.0-beta.6) in a Next.js application, a React hydration error occurs because the library modifies the tag's inline styles during client-side initialization, causing a mismatch between server-rendered HTML and client-rendered HTML.
Error Message

Image Image

A tree hydrated but some attributes of the server rendered HTML didn't match the client properties. This won't be patched up.

Root Cause

In state/effects.ts (lines 8-14), the library uses a Preact signal effect that automatically applies theme CSS custom properties directly to document.documentElement.style:

export const updatedThemeEffect: () => void = effect((): void => {
  if (document) {
    for (const [key, value] of Object.entries(theme.value)) {
      document.documentElement.style.setProperty(`--swk-${key}`, value);
    }
  }
});

This effect is registered at module load time and fires immediately when StellarWalletsKit.init() is called with theme configuration.

Reproduction Steps

  1. Create a Next.js app with SSR enabled
  2. Install jsr:@creit-tech/stellar-wallets-kit@2.0.0-beta.6
  3. Initialize the kit in a client component:
useEffect(() => {
  if (!isClient) return;
  
  StellarWalletsKit.init({
    network: networkType,
    modules: defaultModules(),
    theme: myTheme, // Any theme object
  });
}, [isClient]);

Load the page and observe hydration error in console

Expected Behavior

The library should apply theme styles in a way that's compatible with SSR frameworks like Next.js, avoiding modifications to the tag's inline styles that cause hydration mismatches.

Suggested Solutions

Use a <style> tag instead of inline styles - Inject CSS custom properties via a style tag in the document head
Use class-based theming - Apply theme classes instead of inline CSS variables

Workaround

Currently, users need to suppress hydration warnings on the tag:

<html lang="en" suppressHydrationWarning>

However, this is not ideal as it suppresses all hydration warnings, not just the ones from the wallet kit.

Environment

Package: jsr:@creit-tech/stellar-wallets-kit@2.0.0-beta.6
Framework: Next.js 15.5.3
React: 19.1.1

Metadata

Metadata

Assignees

No one assigned

    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