Skip to content

Feature Request: Add setupJodsRemix() for simplified Remix integration #28

Description

@clamstew

Problem Statement

(from 💡 idea on docs/docs/remix/api-reference.md in https://github.com/clamstew/jods/pull/22/files)

Currently, when using jods with Remix, developers must manually:

  1. Set up a data pipeline from server to client
  2. Call rehydrateClient() in their entry client file
  3. Manually list all stores that need to be hydrated
  4. Ensure window.JODS_DATA is populated in the root layout

This creates several points of friction:

  • Requires boilerplate code in multiple files
  • Easy to forget adding new stores to the hydration list
  • No standardized pattern for SSR hydration
  • Higher learning curve for new developers

Proposed Solution

Add a simplified setupJodsRemix() API that automates the hydration process with minimal configuration:

// Example usage:
import { setupJodsRemix } from 'jods/remix';

// In entry.client.tsx
setupJodsRemix();

Detailed Design

The setupJodsRemix() function would:

  1. Auto-discover stores: Automatically find all jods stores registered in the application
  2. Handle hydration: Read from a standardized window.JODS_DATA property
  3. Provide utilities: Generate components/hooks for root layout integration
  4. Error handling: Provide helpful warnings if setup is incorrect

API Options

function setupJodsRemix(options?: {
  // Optional list of stores to manually specify (falls back to auto-discovery)
  stores?: Array<JodsStore>;
  // Custom location for jods data (defaults to window.__JODS_DATA__)
  dataSource?: string;
  // Enable debug mode with extra console logging
  debug?: boolean;
  // Auto-register with RemixBrowser (for automatic installation)
  autoRegister?: boolean;
}): {
  // Components and utilities to help with setup
  RootProvider: React.ComponentType;
  DataScript: React.ComponentType;
}

Example Implementation in a Remix App

Entry Client (app/entry.client.tsx):

import { hydrateRoot } from 'react-dom/client';
import { RemixBrowser } from '@remix-run/react';
import { setupJodsRemix } from 'jods/remix';

// One line setup - everything else is automatic!
setupJodsRemix();

hydrateRoot(document, <RemixBrowser />);

Root Layout (app/root.tsx):

import { Links, Meta, Outlet, Scripts } from '@remix-run/react';
import { setupJodsRemix } from 'jods/remix';

// Get the components for easy integration
const { DataScript } = setupJodsRemix();

export default function App() {
  return (
    <html lang="en">
      <head>
        <Meta />
        <Links />
      </head>
      <body>
        <Outlet />
        
        {/* Automatically handles data serialization */}
        <DataScript />
        <Scripts />
      </body>
    </html>
  );
}

Implementation Notes

  1. Store Registration System

    • Need a central registry of all defineStore instances
    • Use a singleton pattern to track stores across the app
  2. Root Provider Component

    • Create a provider that handles context for jods stores
    • Make it optional but recommended for advanced features
  3. DataScript Component

    • Generates the script tag with serialized store data
    • Works with withJods() to extract data from loaders
  4. Backwards Compatibility

    • Continue supporting manual rehydrateClient for existing apps
    • Provide a clear migration path

Benefits

  • Reduced boilerplate: Single function call instead of multiple steps
  • Less fragile: No need to manually list stores for hydration
  • Better DX: Simplified mental model for developers
  • Convention over configuration: Works automatically for standard setups

Related Work

This approach is inspired by other framework integrations like Next.js and SvelteKit that provide simplified setup functions for state management libraries.

Metadata

Metadata

Assignees

Labels

enhancementNew feature or requestremixfor use in SSR remix run apps

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions