shakapacker 9.3.0.beta.5 → 9.3.0.beta.7

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 9db05ecb02b4491f31eb4ec2374057933be5cf90a09b6dded781c036ff8e494e
4
- data.tar.gz: a8f9b04812aff8a73275044f61a1ecbc096c5131a3bca69d5b75e292c1c31064
3
+ metadata.gz: 6d74b7ba9b6d6c78f1909339be00ce6d88a6d3f8e8cd64ada499992c3bf6691f
4
+ data.tar.gz: f51ffe665f554536b8defcf139399eb6f6630c61f427a4be9c88aebf14404b25
5
5
  SHA512:
6
- metadata.gz: 88f63fdaaed2cfad42f000d97e08fec78dddaa24b304dd23ae515ba24b5b68845e33115adf13994f0a59f85b6be4003a442e8d5f88a1a9295484ca0b31e07fc1
7
- data.tar.gz: 59069f26686a609a9df9994ec63a1cbc5905d18abbb7379c0460913f16ac58247e760d97eecc544a31a86e212d6af1d171b99f462f4b60b937d0da81d3415a7f
6
+ metadata.gz: 7fa1c2252b25cc3e265e6375561e0be38d1656604e6bf873eb1d6b25d41478bc48c530e8bcac3a05f6d09f7569f988a65cb52609564c87ea35f657bda3baed27
7
+ data.tar.gz: a322b6a94de55f7f8da67d54778e6f455726d4778576e5ff689e2874d68f58b8613260d683d93e019d48d44eeeb9a46a7094be12cb7dbaea76824e688350994a
data/CHANGELOG.md CHANGED
@@ -13,6 +13,22 @@ Changes since the last non-beta release.
13
13
 
14
14
  ### Added
15
15
 
16
+ - **`--help=verbose` flag support** to display all available webpack/rspack bundler options. [PR #763](https://github.com/shakacode/shakapacker/pull/763) by [justin808](https://github.com/justin808).
17
+ - Run `bin/shakapacker --help=verbose` to see complete bundler documentation
18
+ - Shows all webpack CLI options when using webpack
19
+ - Useful for discovering advanced bundler configuration options
20
+ - **Support for arbitrary output names in build configurations**. [PR #752](https://github.com/shakacode/shakapacker/pull/752) by [justin808](https://github.com/justin808).
21
+ - `outputs` array now accepts any custom names (e.g., `client-modern`, `client-legacy`, `server-bundle`)
22
+ - Previously limited to only `client`, `server`, and `all`
23
+ - Enables better organization of multi-config webpack builds
24
+ - **Enhanced error reporting in config exporter**. [PR #752](https://github.com/shakacode/shakapacker/pull/752) by [justin808](https://github.com/justin808).
25
+ - Shows detailed environment variable state when config functions fail
26
+ - Provides actionable suggestions based on error patterns (e.g., missing NODE_ENV)
27
+ - Improved formatting with clear sections for easier debugging
28
+ - **Config count validation for build outputs**. [PR #752](https://github.com/shakacode/shakapacker/pull/752) by [justin808](https://github.com/justin808).
29
+ - Validates webpack/rspack config array length matches `outputs` array
30
+ - Clear error messages when mismatch detected
31
+ - Suggests fixes with example configuration
16
32
  - **HTTP 103 Early Hints support** for faster asset loading. [PR #722](https://github.com/shakacode/shakapacker/pull/722) by [justin808](https://github.com/justin808). Fixes [#721](https://github.com/shakacode/shakapacker/issues/721).
17
33
  - **Automatic sending**: Early hints are sent automatically when `early_hints: enabled: true` in `shakapacker.yml`
18
34
  - **Per-page configuration**: Configure hints per-controller/action with `preload`/`prefetch`/`none` options
@@ -31,7 +47,7 @@ Changes since the last non-beta release.
31
47
  - **Performance note**: May improve or hurt page load performance depending on content - careful testing advised
32
48
  - See [Early Hints Guide](docs/early_hints.md) for detailed usage and advanced patterns
33
49
 
34
- ## [v9.3.0-beta.0] - October 13, 2025
50
+ ## [v9.3.0-beta.5] - October 18, 2025
35
51
 
36
52
  ### Added
37
53
 
@@ -53,6 +69,15 @@ Changes since the last non-beta release.
53
69
  - **Build timing logs** for webpack and rspack. [PR #706](https://github.com/shakacode/shakapacker/pull/706) by [justin808](https://github.com/justin808).
54
70
  - Shows duration of build operations
55
71
  - Helps identify performance bottlenecks
72
+ - **Named build configurations with `--build` flag**. [PR #728](https://github.com/shakacode/shakapacker/pull/728) by [justin808](https://github.com/justin808).
73
+ - Allows specifying custom build configurations: `bin/shakapacker --build=production` or `bin/shakapacker --build=test`
74
+ - Useful for creating specialized build configurations for different deployment environments
75
+ - **Build validation in `bin/export-bundler-config`**. [PR #717](https://github.com/shakacode/shakapacker/pull/717) by [justin808](https://github.com/justin808).
76
+ - Validates webpack/rspack configuration before export to catch errors early
77
+ - Provides clear error messages for configuration issues
78
+ - **Backward compatibility for rspack config in `config/webpack/`**. [PR #734](https://github.com/shakacode/shakapacker/pull/734) by [justin808](https://github.com/justin808).
79
+ - Rspack configurations can now be placed in `config/webpack/` directory for easier migration
80
+ - Maintains compatibility with existing project structures
56
81
  - Added Knip for detecting dead code to CI. [PR #675](https://github.com/shakacode/shakapacker/pull/675) by [justin808](https://github.com/justin808).
57
82
 
58
83
  ### Changed
@@ -80,6 +105,12 @@ Changes since the last non-beta release.
80
105
  - **Improved doctor command output** clarity and accuracy. [PR #682](https://github.com/shakacode/shakapacker/pull/682) by [justin808](https://github.com/justin808).
81
106
  - Better formatting and organization of diagnostic information
82
107
  - More actionable recommendations
108
+ - **Documented `content_for` pattern to prevent FOUC** with `stylesheet_pack_tag`. [PR #737](https://github.com/shakacode/shakapacker/pull/737) by [justin808](https://github.com/justin808).
109
+ - Added documentation on using `content_for` to prevent Flash of Unstyled Content
110
+ - Best practice patterns for managing stylesheet loading order
111
+ - **Improved upgrade documentation** to clarify dual Gemfile and package.json updates. [PR #731](https://github.com/shakacode/shakapacker/pull/731) by [justin808](https://github.com/justin808).
112
+ - Clearer instructions for upgrading both Ruby gem and NPM package
113
+ - Helps prevent version mismatch issues
83
114
  - Formatted all markdown files with prettier. [PR #673](https://github.com/shakacode/shakapacker/pull/673) by [justin808](https://github.com/justin808).
84
115
 
85
116
  ### Fixed
@@ -752,8 +783,8 @@ Note: [Rubygem is 6.3.0.pre.rc.1](https://rubygems.org/gems/shakapacker/versions
752
783
 
753
784
  See [CHANGELOG.md in rails/webpacker (up to v5.4.3)](https://github.com/rails/webpacker/blob/master/CHANGELOG.md)
754
785
 
755
- [Unreleased]: https://github.com/shakacode/shakapacker/compare/v9.3.0-beta.0...main
756
- [v9.3.0-beta.0]: https://github.com/shakacode/shakapacker/compare/v9.2.0...v9.3.0-beta.0
786
+ [Unreleased]: https://github.com/shakacode/shakapacker/compare/v9.3.0-beta.5...main
787
+ [v9.3.0-beta.5]: https://github.com/shakacode/shakapacker/compare/v9.2.0...v9.3.0-beta.5
757
788
  [v9.2.0]: https://github.com/shakacode/shakapacker/compare/v9.1.0...v9.2.0
758
789
  [v9.1.0]: https://github.com/shakacode/shakapacker/compare/v9.0.0...v9.1.0
759
790
  [v9.0.0]: https://github.com/shakacode/shakapacker/compare/v8.4.0...v9.0.0
@@ -6,7 +6,7 @@ This document tracks the ESLint errors currently suppressed in the codebase and
6
6
 
7
7
  **As of 2025-10-14**: All TypeScript files in `package/` directory are temporarily excluded from linting via the ignore pattern `package/**/*.ts` in `eslint.config.js`. This allows the project to adopt ESLint configuration without requiring immediate fixes to all existing issues.
8
8
 
9
- **Latest Update**: Fixed all `no-param-reassign` violations by refactoring to create new objects instead of mutating parameters (7 violations resolved).
9
+ **Latest Update**: Auto-fixed 28 style violations in `package/configExporter/cli.ts` including unnecessary type assertions, string concatenation to template literals, and object destructuring (reduced from 77 to 49 errors).
10
10
 
11
11
  ## Current Linting Status
12
12
 
@@ -24,7 +24,7 @@ This document tracks the ESLint errors currently suppressed in the codebase and
24
24
  - Style/convention issues: ~49 (30%)
25
25
 
26
26
  **Target**: Reduce suppressed errors by 50% within Q1 2025
27
- **Last Updated**: 2025-10-15
27
+ **Last Updated**: 2025-10-18
28
28
 
29
29
  ## Priority Matrix
30
30
 
@@ -115,6 +115,12 @@ This document tracks the ESLint errors currently suppressed in the codebase and
115
115
  - ✅ **Fixed `class-methods-use-this`** - Converted FileWriter methods to static methods
116
116
  - ✅ **Fixed `no-nested-ternary`** - Refactored to if-else statements for better readability
117
117
  - ✅ **Fixed `no-param-reassign`** - Refactored `applyDefaults` to return new objects instead of mutating parameters
118
+ - ✅ **Auto-fixed style violations in cli.ts** (2025-10-18):
119
+ - Removed unnecessary type assertions (`@typescript-eslint/no-unnecessary-type-assertion`)
120
+ - Used object destructuring (`prefer-destructuring`)
121
+ - Converted string concatenation to template literals (`prefer-template`)
122
+ - Removed unused eslint-disable directives
123
+ - Fixed `no-else-return` violations
118
124
 
119
125
  🔧 Could still fix (low risk):
120
126
 
data/Gemfile.lock CHANGED
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- shakapacker (9.3.0.beta.5)
4
+ shakapacker (9.3.0.beta.7)
5
5
  activesupport (>= 5.2)
6
6
  package_json
7
7
  rack-proxy (>= 0.6.1)
data/docs/early_hints.md CHANGED
@@ -2,6 +2,8 @@
2
2
 
3
3
  This guide shows you how to use HTTP 103 Early Hints with Shakapacker to optimize page load performance.
4
4
 
5
+ > **📚 Related Documentation:** For advanced manual control using `send_pack_early_hints` in controllers before expensive work, see [early_hints_manual_api.md](early_hints_manual_api.md).
6
+
5
7
  ## What are Early Hints?
6
8
 
7
9
  HTTP 103 Early Hints is emitted **after** Rails has finished rendering but **before** the final response is sent, allowing browsers to begin fetching resources (JS, CSS) prior to receiving the full HTML response. This may significantly improve page load performance or cause an equally significant regression, depending on the page's content.
@@ -316,29 +318,13 @@ Shakapacker automatically sends early hints after your views render:
316
318
 
317
319
  ## Advanced: Manual Control
318
320
 
319
- Most apps should use controller configuration. Use manual control for view-specific logic:
320
-
321
- ```erb
322
- <%# app/views/layouts/application.html.erb %>
323
- <% send_pack_early_hints css: 'prefetch', js: 'preload' %>
321
+ Most apps should use controller configuration. For advanced use cases including:
324
322
 
325
- <!DOCTYPE html>
326
- <html>
327
- <body>
328
- <%= yield %>
329
- <%= javascript_pack_tag 'application' %>
330
- </body>
331
- </html>
332
- ```
333
-
334
- **Per-tag override:**
335
-
336
- ```erb
337
- <%= javascript_pack_tag 'application',
338
- early_hints: { css: 'preload', js: 'prefetch' } %>
339
- ```
323
+ - Sending hints **before** expensive controller work for maximum parallelism
324
+ - Per-pack customization in layouts
325
+ - View-specific logic
340
326
 
341
- **Use cases:** Layout-specific optimizations, conditional hints based on view variables, A/B testing
327
+ See the [Manual API Guide](early_hints_manual_api.md) for detailed examples and patterns.
342
328
 
343
329
  ## Requirements
344
330
 
@@ -1,4 +1,16 @@
1
- # HTTP 103 Early Hints - New API
1
+ # HTTP 103 Early Hints - Manual API Guide
2
+
3
+ > **📚 Main Documentation:** This guide covers the manual `send_pack_early_hints` API for advanced use cases. For the recommended controller-based API (`configure_pack_early_hints`, `skip_send_pack_early_hints`) and comprehensive setup instructions, see [early_hints.md](early_hints.md).
4
+
5
+ This guide focuses on **manual control** of early hints for advanced scenarios where you need to send hints before expensive controller work or customize hints per-pack in layouts.
6
+
7
+ ## Automatic vs Manual API
8
+
9
+ By default, Shakapacker automatically sends early hints when `javascript_pack_tag` and `stylesheet_pack_tag` are called (after views render). The manual API allows you to:
10
+
11
+ - **Send hints earlier** - Before controller work starts, maximizing parallelism
12
+ - **Customize per-pack** - Different strategies for different packs in the same layout
13
+ - **Override automatic behavior** - When you need fine-grained control
2
14
 
3
15
  ## ⚠️ IMPORTANT: Performance Testing Required
4
16
 
@@ -14,73 +26,21 @@
14
26
  2. Measure Core Web Vitals (LCP, FCP, TTI) for both groups
15
27
  3. Only keep enabled if metrics improve
16
28
 
17
- See [Troubleshooting](#performance-got-worse) if early hints decrease performance.
18
-
19
- ---
20
-
21
- ## Prerequisites
22
-
23
- Before implementing early hints, verify you have:
24
-
25
- 1. **Puma 5+** with `--early-hints` flag (REQUIRED)
26
- 2. **HTTP/2-capable proxy** in front of Puma:
27
- - ✅ Thruster (Rails 8 default)
28
- - ✅ nginx 1.13+
29
- - ✅ Cloudflare (paid plans)
30
- - ❌ Control Plane (strips 103 responses)
31
- - ❌ AWS ALB/ELB (strips 103 responses)
32
- 3. **Rails 5.2+** (for `request.send_early_hints` API)
33
-
34
- **Critical**: Puma requires the `--early-hints` flag to send HTTP 103:
35
-
36
- ```bash
37
- # Procfile / Dockerfile
38
- web: bundle exec puma --early-hints -C config/puma.rb
39
- ```
40
-
41
- Without this flag, early hints will NOT work. See [Setup](#production-setup) for details.
42
-
43
- ---
44
-
45
- ## Quick Start
29
+ See the [Feature Testing Guide](feature_testing.md#http-103-early-hints) for testing instructions and the [main documentation](early_hints.md) for comprehensive troubleshooting.
46
30
 
47
- ### Pattern 1: Automatic (Default)
31
+ ## When to Use the Manual API
48
32
 
49
- By default, `javascript_pack_tag` and `stylesheet_pack_tag` automatically send early hints when early hints are enabled in config:
50
-
51
- ```yaml
52
- # config/shakapacker.yml
53
- production:
54
- early_hints:
55
- enabled: true
56
- ```
57
-
58
- ```erb
59
- <%# app/views/layouts/application.html.erb %>
60
- <!DOCTYPE html>
61
- <html>
62
- <head>
63
- <%# Automatically sends early hints for application pack CSS %>
64
- <%= stylesheet_pack_tag 'application' %>
65
- </head>
66
- <body>
67
- <%= yield %>
68
- <%# Automatically sends early hints for application pack JS %>
69
- <%= javascript_pack_tag 'application' %>
70
- </body>
71
- </html>
72
- ```
33
+ Use `send_pack_early_hints` when you need:
73
34
 
74
- **How it works:**
35
+ 1. **Maximum parallelism** - Send hints BEFORE expensive controller work (database queries, API calls)
36
+ 2. **Per-pack customization** - Different hint strategies for different packs in layouts
37
+ 3. **Dynamic control** - Runtime decisions about which packs to hint
75
38
 
76
- - When `stylesheet_pack_tag` is called, it automatically sends CSS early hints
77
- - When `javascript_pack_tag` is called, it automatically sends JS early hints
78
- - Combines queue (from `append_*_pack_tag`) + direct args
79
- - Default: `rel=preload` for all packs
39
+ For most applications, use the [controller-based API](early_hints.md#controller-configuration) instead (`configure_pack_early_hints`, `skip_send_pack_early_hints`).
80
40
 
81
- ---
41
+ ## Manual API Patterns
82
42
 
83
- ## Pattern 2: Per-Pack Customization in Layout
43
+ ### Pattern 1: Per-Pack Customization in Layout
84
44
 
85
45
  Customize hint handling per pack using a hash:
86
46
 
@@ -109,7 +69,7 @@ Customize hint handling per pack using a hash:
109
69
 
110
70
  ---
111
71
 
112
- ## Pattern 3: Controller Override (Before Expensive Work)
72
+ ### Pattern 2: Controller Override (Before Expensive Work)
113
73
 
114
74
  Send hints manually in controller BEFORE expensive work to maximize parallelism:
115
75
 
@@ -148,7 +108,7 @@ end
148
108
 
149
109
  ---
150
110
 
151
- ## Pattern 4: View Override
111
+ ### Pattern 3: View Override
152
112
 
153
113
  Views can use `append_*_pack_tag` to add packs dynamically:
154
114
 
@@ -188,13 +148,7 @@ Views can use `append_*_pack_tag` to add packs dynamically:
188
148
 
189
149
  ## Configuration
190
150
 
191
- ```yaml
192
- # config/shakapacker.yml
193
- production:
194
- early_hints:
195
- enabled: true # Master switch (default: false)
196
- debug: true # Show HTML comments with debug info (default: false)
197
- ```
151
+ > **📚 Configuration:** See the [main documentation](early_hints.md#quick-start) for all configuration options including global settings, priority levels (preload/prefetch/none), and per-controller configuration.
198
152
 
199
153
  ---
200
154
 
@@ -226,26 +180,20 @@ end
226
180
 
227
181
  ## When to Use Each Pattern
228
182
 
229
- ### Pattern 1 (Automatic) - Best for:
230
-
231
- - Simple apps with consistent performance
232
- - Small/medium JS bundles (<500KB)
233
- - Fast controllers (<100ms)
234
-
235
- ### Pattern 2 (Per-Pack) - Best for:
183
+ ### Pattern 1 (Per-Pack) - Best for:
236
184
 
237
185
  - Mixed vendor bundles (preload critical, prefetch non-critical)
238
186
  - Different handling for different packs
239
187
  - Layout-specific optimizations
240
188
 
241
- ### Pattern 3 (Controller) - Best for:
189
+ ### Pattern 2 (Controller) - Best for:
242
190
 
243
191
  - Slow controllers with expensive queries (>300ms)
244
192
  - Large JS bundles (>500KB)
245
193
  - APIs calls in controller
246
194
  - Maximum parallelism needed
247
195
 
248
- ### Pattern 4 (View Override) - Best for:
196
+ ### Pattern 3 (View Override) - Best for:
249
197
 
250
198
  - Admin sections with extra packs
251
199
  - Feature flags determining packs
@@ -259,11 +207,11 @@ end
259
207
  # app/controllers/posts_controller.rb
260
208
  class PostsController < ApplicationController
261
209
  def index
262
- # Fast controller, use automatic hints
210
+ # Fast controller, automatic hints work fine (Pattern 1)
263
211
  end
264
212
 
265
213
  def show
266
- # Slow controller, send hints early
214
+ # Slow controller, send hints early for parallelism (Pattern 2)
267
215
  send_pack_early_hints({
268
216
  "application" => { js: "preload", css: "preload" }
269
217
  })
@@ -277,6 +225,7 @@ end
277
225
  ```erb
278
226
  <%# app/views/posts/show.html.erb %>
279
227
  <% if current_user&.admin? %>
228
+ <%# Pattern 3: Dynamic pack loading based on user role %>
280
229
  <% append_javascript_pack_tag 'admin_tools' %>
281
230
  <% end %>
282
231
  ```
@@ -286,13 +235,12 @@ end
286
235
  <!DOCTYPE html>
287
236
  <html>
288
237
  <head>
289
- <%# Automatic CSS hints for application %>
290
238
  <%= stylesheet_pack_tag 'application' %>
291
239
  </head>
292
240
  <body>
293
241
  <%= yield %>
294
242
 
295
- <%# Automatic JS hints for application + admin_tools (if appended) %>
243
+ <%# Sends hints for application + admin_tools (if appended) %>
296
244
  <%# Won't duplicate hints already sent in controller %>
297
245
  <%= javascript_pack_tag 'application' %>
298
246
  </body>
@@ -303,7 +251,9 @@ end
303
251
 
304
252
  ## Preloading Non-Pack Assets (Images, Videos, Fonts)
305
253
 
306
- **Shakapacker's early hints are for pack assets (JS/CSS bundles).** For non-pack assets like hero images, videos, and fonts, you have two options:
254
+ **Shakapacker's early hints are for pack assets (JS/CSS bundles).** For non-pack assets like hero images, videos, and fonts, you have two options.
255
+
256
+ > **Note:** The [main documentation](early_hints.md#4-preloading-hero-images-and-videos) covers using Rails' built-in `preload_link_tag` for images and videos, which is simpler than the manual approach below.
307
257
 
308
258
  ### Option 1: Manual Early Hints (For LCP/Critical Assets)
309
259
 
@@ -379,7 +329,9 @@ Use Rails' `preload_link_tag` to add `<link rel="preload">` in the HTML:
379
329
 
380
330
  ## Requirements & Limitations
381
331
 
382
- **IMPORTANT:** Before implementing Early Hints, understand these limitations:
332
+ > **📚 Full Requirements:** See the [main documentation](early_hints.md#requirements) for complete browser and server requirements. This section covers limitations specific to the manual API.
333
+
334
+ **IMPORTANT:** Understand these limitations when using the manual API:
383
335
 
384
336
  ### Architecture: Proxy Required for HTTP/2
385
337
 
@@ -426,14 +378,10 @@ Browser (HTTP/2 103) ✅
426
378
  - Subsequent 103 responses are ignored by browsers
427
379
  - This is by design per the HTTP 103 spec
428
380
 
429
- ### Browser Support
430
-
431
- - Chrome/Firefox 103+
432
- - Safari 16.4+
433
- - Gracefully degrades if not supported
434
-
435
381
  ### Testing Locally
436
382
 
383
+ > **📚 Full Testing Guide:** See the [Feature Testing Guide](feature_testing.md#http-103-early-hints) for comprehensive testing instructions with browser DevTools and curl.
384
+
437
385
  **Step 1: Enable early hints in your test environment**
438
386
 
439
387
  ```yaml
@@ -478,223 +426,29 @@ curl -v http://localhost:3000/
478
426
 
479
427
  ### Production Setup
480
428
 
481
- #### Thruster (Rails 8+ Default)
482
-
483
- **Recommended**: Use [Thruster](https://github.com/basecamp/thruster) in front of Puma (Rails 8 default).
484
-
485
- Thruster handles HTTP/2 → HTTP/1.1 translation automatically. No configuration needed - Early Hints just work.
486
-
487
- ```dockerfile
488
- # Dockerfile (Rails 8 default)
489
- CMD ["bundle", "exec", "thrust", "./bin/rails", "server"]
490
- ```
491
-
492
- Thruster will:
493
-
494
- 1. Receive HTTP/2 requests from browsers
495
- 2. Translate to HTTP/1.1 for Puma
496
- 3. Pass through HTTP/1.1 103 Early Hints from Puma
497
- 4. Translate to HTTP/2 103 for browsers
498
-
499
- #### Control Plane
500
-
501
- **Status: Early Hints NOT supported** ❌
502
-
503
- Control Plane's load balancer appears to strip HTTP 103 responses, even with correct configuration:
504
-
505
- - Puma sends HTTP/1.1 103 ✅ (verified locally with curl)
506
- - Control Plane LB strips 103 before reaching browser ❌
507
- - Workload protocol set to `HTTP` (not `HTTP2`) ✅
508
- - Puma started with `--early-hints` flag ✅
509
-
510
- **Recommendation**: If you need early hints, consider:
511
-
512
- - **Thruster** (Rails 8 default, supports early hints)
513
- - **Self-hosted nginx** (supports early hints)
514
- - **Cloudflare** (paid plans only)
515
- - Contact Control Plane support to request early hints support
516
-
517
- #### nginx (Self-Hosted)
518
-
519
- If you want HTTP/2 in production with self-hosted nginx:
520
-
521
- ```nginx
522
- # /etc/nginx/sites-available/myapp
523
- upstream puma {
524
- server unix:///var/www/myapp/tmp/sockets/puma.sock;
525
- }
526
-
527
- server {
528
- listen 443 ssl http2;
529
- server_name example.com;
530
-
531
- # SSL certificates
532
- ssl_certificate /path/to/cert.pem;
533
- ssl_certificate_key /path/to/key.pem;
534
-
535
- location / {
536
- proxy_pass http://puma; # Puma uses HTTP/1.1
537
- proxy_set_header Host $host;
538
- proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
539
- proxy_set_header X-Forwarded-Proto $scheme;
540
-
541
- # CRITICAL: Pass through Early Hints from Puma
542
- proxy_pass_header Link;
543
- }
544
- }
545
- ```
546
-
547
- nginx will:
429
+ > **📚 Production Setup:** See the [main documentation](early_hints.md#requirements) for complete production setup instructions including Puma configuration, proxy setup (Thruster, nginx, Cloudflare), and troubleshooting proxy issues.
548
430
 
549
- 1. Receive HTTP/2 request from browser
550
- 2. Forward as HTTP/1.1 to Puma
551
- 3. Receive HTTP/1.1 103 from Puma
552
- 4. Translate to HTTP/2 103 for browser
431
+ **Quick checklist:**
553
432
 
554
- ---
555
-
556
- ## Troubleshooting
557
-
558
- ### Early Hints Not Appearing
559
-
560
- **Step 1: Enable debug mode to see what Puma is sending**
561
-
562
- ```yaml
563
- # config/shakapacker.yml
564
- development:
565
- early_hints:
566
- enabled: true
567
- debug: true # Shows hints in HTML comments
568
- ```
569
-
570
- Reload your page and check the HTML source for comments like:
571
-
572
- ```html
573
- <!-- Early hints sent (JS): application=preload -->
574
- <!-- Early hints sent (CSS): application=preload -->
575
- ```
576
-
577
- **If debug shows hints are sent:**
578
-
579
- The issue is with your **proxy/infrastructure**, not Shakapacker. Proceed to Step 2.
580
-
581
- **If debug shows NO hints sent:**
582
-
583
- Check your config:
584
-
585
- - `early_hints.enabled: true` in `config/shakapacker.yml`
433
+ - Puma 5+ with `--early-hints` flag (REQUIRED)
434
+ - HTTP/2-capable proxy (Thruster ✅, nginx ✅, Cloudflare ✅, Control Plane ❌, AWS ALB ❌)
586
435
  - Rails 5.2+
587
- - Puma 5+
588
- - **Puma started with `--early-hints` flag** (REQUIRED!)
589
-
590
- ---
591
-
592
- **Step 2: Check if your proxy is stripping 103 responses**
593
-
594
- This is the **most common cause** of missing early hints.
595
-
596
- Test with curl against your local Puma (HTTP/1.1):
597
-
598
- ```bash
599
- # Direct to Puma (should work)
600
- curl -v http://localhost:3000/
601
-
602
- # Look for:
603
- < HTTP/1.1 103 Early Hints
604
- < link: </packs/application.js>; rel=preload; as=script
605
- <
606
- < HTTP/1.1 200 OK
607
- ```
608
-
609
- If you see the 103 response, Puma is working correctly.
610
-
611
- ---
612
-
613
- **Step 3: Common proxy issues**
614
-
615
- #### Control Plane
616
-
617
- **Status: NOT supported** ❌
618
-
619
- Control Plane strips HTTP 103 responses. No known workaround. Consider switching to Thruster, nginx, or Cloudflare if you need early hints.
620
-
621
- #### AWS ALB/ELB
622
-
623
- **Not supported** - ALBs strip 103 responses entirely. No workaround except:
624
-
625
- - Skip ALB (not recommended)
626
- - Use CloudFront in front (CloudFront supports early hints)
627
-
628
- #### Cloudflare
629
-
630
- Enable "Early Hints" in dashboard:
631
-
632
- ```
633
- Speed > Optimization > Early Hints: ON
634
- ```
635
-
636
- **Note:** Paid plans only (Pro/Business/Enterprise).
637
-
638
- #### nginx
639
-
640
- nginx 1.13+ passes 103 responses automatically. Ensure you're using HTTP/2:
641
-
642
- ```nginx
643
- server {
644
- listen 443 ssl http2; # Enable HTTP/2
645
-
646
- location / {
647
- proxy_pass http://puma; # Puma uses HTTP/1.1
648
- proxy_http_version 1.1; # Required for Puma
649
- }
650
- }
651
- ```
652
-
653
- No special configuration needed - nginx automatically translates HTTP/1.1 103 to HTTP/2 103.
654
-
655
- #### Thruster (Rails 8+)
656
-
657
- Thruster handles HTTP/2 → HTTP/1.1 translation automatically. Early hints just work. No configuration needed.
658
436
 
659
437
  ---
660
438
 
661
- ### Debugging Checklist
662
-
663
- 1. ✅ **Config enabled:** `early_hints.enabled: true` in `shakapacker.yml`
664
- 2. ✅ **Puma `--early-hints` flag:** Puma started with this flag (REQUIRED!)
665
- 3. ✅ **Debug mode on:** See HTML comments confirming hints sent
666
- 4. ✅ **Puma 5+:** Early hints require Puma 5+
667
- 5. ✅ **Rails 5.2+:** `request.send_early_hints` API available
668
- 6. ✅ **Architecture:** Proxy in front of Puma (Thruster, nginx - NOT Control Plane or AWS ALB)
669
- 7. ✅ **Puma protocol:** Always HTTP/1.1 (never HTTP/2)
670
- 8. ✅ **Proxy protocol:** HTTP/2 to browser, HTTP/1.1 to Puma
671
- 9. ✅ **Browser support:** Chrome 103+, Firefox 103+, Safari 16.4+
672
-
673
- ---
674
-
675
- ### Performance Got Worse?
676
-
677
- If enabling early hints **decreased** performance:
678
-
679
- **Likely cause:** Page has large images/videos as LCP (Largest Contentful Paint).
439
+ ## Troubleshooting
680
440
 
681
- Preloading large JS bundles can delay image downloads, hurting LCP.
441
+ > **📚 Complete Troubleshooting:** See the [main documentation](early_hints.md#troubleshooting) for comprehensive troubleshooting including debug mode, proxy configuration, and performance optimization.
682
442
 
683
- **Fix:**
443
+ Quick debugging steps:
684
444
 
685
- ```yaml
686
- # config/shakapacker.yml
687
- production:
688
- early_hints:
689
- enabled: true
690
- css: "prefetch" # Lower priority
691
- js: "prefetch" # Lower priority
692
- ```
693
-
694
- Or disable entirely and use HTML `preload_link_tag` for images instead.
695
-
696
- ---
445
+ 1. Enable `debug: true` in shakapacker.yml to see hints in HTML comments
446
+ 2. Verify Puma started with `--early-hints` flag
447
+ 3. Test with `curl -v http://localhost:3000/` to see if Puma sends 103 responses
448
+ 4. Check if your proxy strips 103 responses (Control Plane ❌, AWS ALB ❌)
697
449
 
698
450
  ### Reference
699
451
 
452
+ - [Main Early Hints Documentation](early_hints.md)
453
+ - [Feature Testing Guide](feature_testing.md#http-103-early-hints)
700
454
  - [Rails 103 Early Hints Analysis](https://island94.org/2025/10/rails-103-early-hints-could-be-better-maybe-doesn-t-matter)