eslint-rules/README.md
This directory contains custom ESLint rules specific to React on Rails.
no-use-client-in-server-filesPrevents the 'use client' directive from being used in .server.tsx and .server.ts files.
Files ending with .server.tsx are intended for server-side rendering in React Server Components (RSC) architecture. The 'use client' directive forces webpack to bundle these files as client components, which creates a fundamental contradiction and causes errors when using React's react-server conditional exports.
This issue became apparent with Shakapacker 9.3.0+, which properly honors resolve.conditionNames in webpack configurations. When webpack resolves imports with the react-server condition, React's server exports intentionally omit client-only APIs like:
createContext, useContextuseState, useEffect, useLayoutEffect, useReducerComponent, PureComponentuse* functions)❌ Incorrect - Will trigger an error:
// Component.server.tsx
'use client';
import React from 'react';
export function MyComponent() {
return <div>Component</div>;
}
✅ Correct - No directive in server files:
// Component.server.tsx
import React from 'react';
export function MyComponent() {
return <div>Component</div>;
}
✅ Correct - Use 'use client' in client files:
// Component.client.tsx or Component.tsx
'use client';
import React, { useState } from 'react';
export function MyComponent() {
const [count, setCount] = useState(0);
return <div>Count: {count}</div>;
}
This rule includes an automatic fixer that will remove the 'use client' directive from .server.tsx files when you run ESLint with the --fix option:
npx eslint --fix path/to/file.server.tsx
This rule is automatically enabled in the React on Rails ESLint configuration at the error level. It's defined in eslint.config.ts:
plugins: {
'react-on-rails': {
rules: {
'no-use-client-in-server-files': noUseClientInServerFiles,
},
},
},
rules: {
'react-on-rails/no-use-client-in-server-files': 'error',
// ... other rules
}
To run tests for the custom rules:
node eslint-rules/no-use-client-in-server-files.test.cjs
To add a new custom ESLint rule:
.cjs extension for CommonJS)rule-name.test.cjs)eslint.config.ts