universal_renderer 0.3.2 → 0.4.0
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 +4 -4
- data/README.md +21 -15
- data/lib/universal_renderer/client/stream/execution.rb +8 -8
- data/lib/universal_renderer/renderable.rb +7 -29
- data/lib/universal_renderer/version.rb +1 -1
- metadata +1 -1
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: a84ac507fd401a10c8d36c9b7600d02b4403d84bdcbd63a0c4ac1f707efe0a7f
|
4
|
+
data.tar.gz: deac3f050553555b313864a1eb06ea69ff8e8d25ed78c47a70cb0c54e562012e
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: cda8091a0ad83367e3a0e8bcb93d560ce4b9e778cc543b7edba4084d0e7a540eda82fcd952e40b00115fef62326d15f760de905d882c607224047565d58c9c96
|
7
|
+
data.tar.gz: 15a2798e31d87ca6eec64e0613fedf2da515db85f3b798a792b0917d1719e970862c476c51eaebf65d8550dc0885bd5619edf662819085e3a132d877a4bdf73b
|
data/README.md
CHANGED
@@ -187,23 +187,22 @@ To set up the SSR server for your Rails application:
|
|
187
187
|
4. Create an SSR entry point at `app/frontend/ssr/ssr.ts`:
|
188
188
|
|
189
189
|
```ts
|
190
|
-
import { renderToString } from "react-dom/server";
|
190
|
+
import { renderToString } from "react-dom/server.node";
|
191
191
|
import { createSsrServer } from "universal-renderer";
|
192
|
-
import { createServer as createViteServer } from "vite";
|
193
|
-
|
194
192
|
import setup from "@/ssr/setup";
|
195
|
-
|
196
|
-
|
197
|
-
|
198
|
-
|
199
|
-
|
193
|
+
import {
|
194
|
+
createRenderStreamTransformer,
|
195
|
+
extractMeta,
|
196
|
+
getRequestLogger,
|
197
|
+
getStateElement,
|
198
|
+
} from "@/ssr/utils";
|
200
199
|
|
201
200
|
const app = await createSsrServer({
|
202
|
-
|
201
|
+
middleware: (app) => {
|
202
|
+
app.use(getRequestLogger());
|
203
|
+
},
|
203
204
|
callbacks: {
|
204
|
-
|
205
|
-
// since Vite's ssrLoadModule doesn't include the types
|
206
|
-
setup: (await vite.ssrLoadModule("@/ssr/setup")).default as typeof setup,
|
205
|
+
setup: setup,
|
207
206
|
render: async ({ jsx, helmetContext, sheet, state }) => {
|
208
207
|
const root = renderToString(jsx);
|
209
208
|
const meta = extractMeta(helmetContext);
|
@@ -214,9 +213,16 @@ To set up the SSR server for your Rails application:
|
|
214
213
|
sheet?.seal();
|
215
214
|
queryClient?.clear();
|
216
215
|
},
|
217
|
-
|
218
|
-
|
219
|
-
|
216
|
+
error: (error, _, errorContext) => {
|
217
|
+
console.error(`[SSR] ${errorContext} error:`, error);
|
218
|
+
},
|
219
|
+
},
|
220
|
+
streamCallbacks: {
|
221
|
+
getReactNode: async ({ jsx }) => jsx,
|
222
|
+
getMetaTags: async ({ helmetContext }) => extractMeta(helmetContext),
|
223
|
+
createRenderStreamTransformer,
|
224
|
+
onBeforeWriteClosingHtml: async (res, { state }) => {
|
225
|
+
res.write(getStateElement(state) + "\n");
|
220
226
|
},
|
221
227
|
},
|
222
228
|
});
|
@@ -13,7 +13,7 @@ module UniversalRenderer
|
|
13
13
|
Execution._handle_node_response_streaming(
|
14
14
|
node_res,
|
15
15
|
response,
|
16
|
-
stream_uri
|
16
|
+
stream_uri,
|
17
17
|
)
|
18
18
|
|
19
19
|
return true
|
@@ -28,18 +28,18 @@ module UniversalRenderer
|
|
28
28
|
Execution._handle_streaming_for_node_error(
|
29
29
|
node_res,
|
30
30
|
response,
|
31
|
-
stream_uri
|
31
|
+
stream_uri,
|
32
32
|
)
|
33
33
|
end
|
34
34
|
rescue StandardError => e
|
35
35
|
Rails.logger.error(
|
36
|
-
"Error during SSR data transfer or stream writing from #{stream_uri}: #{e.class.name} - #{e.message}"
|
36
|
+
"Error during SSR data transfer or stream writing from #{stream_uri}: #{e.class.name} - #{e.message}",
|
37
37
|
)
|
38
38
|
|
39
39
|
Execution._write_generic_html_error(
|
40
40
|
response.stream,
|
41
41
|
"Streaming Error",
|
42
|
-
"<p>A problem occurred while loading content. Please refresh.</p>"
|
42
|
+
"<p>A problem occurred while loading content. Please refresh.</p>",
|
43
43
|
)
|
44
44
|
ensure
|
45
45
|
response.stream.close unless response.stream.closed?
|
@@ -53,7 +53,7 @@ module UniversalRenderer
|
|
53
53
|
|
54
54
|
def _handle_streaming_for_node_error(node_res, response, stream_uri)
|
55
55
|
Rails.logger.error(
|
56
|
-
"SSR stream server at #{stream_uri} responded with #{node_res.code} #{node_res.message}."
|
56
|
+
"SSR stream server at #{stream_uri} responded with #{node_res.code} #{node_res.message}.",
|
57
57
|
)
|
58
58
|
|
59
59
|
is_potentially_viewable_error =
|
@@ -61,19 +61,19 @@ module UniversalRenderer
|
|
61
61
|
|
62
62
|
if is_potentially_viewable_error
|
63
63
|
Rails.logger.info(
|
64
|
-
"Attempting to stream HTML error page from Node SSR server."
|
64
|
+
"Attempting to stream HTML error page from Node SSR server.",
|
65
65
|
)
|
66
66
|
Execution._stream_response_body(node_res, response.stream)
|
67
67
|
else
|
68
68
|
Rails.logger.warn(
|
69
69
|
"Node SSR server error response Content-Type ('#{node_res["Content-Type"]}') is not text/html. " \
|
70
|
-
"Injecting generic error message into the stream."
|
70
|
+
"Injecting generic error message into the stream.",
|
71
71
|
)
|
72
72
|
|
73
73
|
Execution._write_generic_html_error(
|
74
74
|
response.stream,
|
75
75
|
"Application Error",
|
76
|
-
"<p>There was an issue rendering this page. Please try again later.</p>"
|
76
|
+
"<p>There was an issue rendering this page. Please try again later.</p>",
|
77
77
|
)
|
78
78
|
end
|
79
79
|
end
|
@@ -45,7 +45,8 @@ module UniversalRenderer
|
|
45
45
|
return super unless request.format.html?
|
46
46
|
|
47
47
|
if use_ssr_streaming?
|
48
|
-
render_ssr_stream(*args, **kwargs)
|
48
|
+
success = render_ssr_stream(*args, **kwargs)
|
49
|
+
super unless success
|
49
50
|
else
|
50
51
|
fetch_ssr
|
51
52
|
super
|
@@ -55,36 +56,27 @@ module UniversalRenderer
|
|
55
56
|
private
|
56
57
|
|
57
58
|
def render_ssr_stream(*args, **kwargs)
|
58
|
-
set_streaming_headers
|
59
|
-
|
60
59
|
full_layout = render_to_string(*args, **kwargs)
|
61
|
-
|
62
|
-
split_index = full_layout.index(SSR::Placeholders::META)
|
63
|
-
before_meta = full_layout[0...split_index]
|
64
|
-
after_meta = full_layout[split_index..]
|
65
|
-
|
66
|
-
response.stream.write(before_meta)
|
67
|
-
|
68
60
|
current_props = @universal_renderer_props.dup
|
69
61
|
|
70
62
|
streaming_succeeded =
|
71
63
|
UniversalRenderer::Client::Stream.stream(
|
72
64
|
request.original_url,
|
73
65
|
current_props,
|
74
|
-
|
66
|
+
full_layout,
|
75
67
|
response,
|
76
68
|
)
|
77
69
|
|
78
70
|
# SSR streaming failed or was not possible (e.g. server down, config missing).
|
79
|
-
|
71
|
+
if streaming_succeeded
|
72
|
+
response.stream.close unless response.stream.closed?
|
73
|
+
else
|
80
74
|
Rails.logger.error(
|
81
75
|
"SSR stream fallback: " \
|
82
76
|
"Streaming failed, proceeding with standard rendering.",
|
83
77
|
)
|
84
|
-
|
78
|
+
false
|
85
79
|
end
|
86
|
-
|
87
|
-
response.stream.close unless response.stream.closed?
|
88
80
|
end
|
89
81
|
|
90
82
|
def initialize_props
|
@@ -144,19 +136,5 @@ module UniversalRenderer
|
|
144
136
|
@universal_renderer_props[prop_key] << value_to_add
|
145
137
|
end
|
146
138
|
end
|
147
|
-
|
148
|
-
def set_streaming_headers
|
149
|
-
# Tell Cloudflare / proxies not to cache or buffer.
|
150
|
-
response.headers["Cache-Control"] = "no-cache, no-store, must-revalidate"
|
151
|
-
response.headers["Pragma"] = "no-cache"
|
152
|
-
response.headers["Expires"] = "0"
|
153
|
-
|
154
|
-
# Disable Nginx buffering per-response.
|
155
|
-
response.headers["X-Accel-Buffering"] = "no"
|
156
|
-
response.headers["Content-Type"] = "text/html"
|
157
|
-
|
158
|
-
# Remove Content-Length header to prevent buffering.
|
159
|
-
response.headers.delete("Content-Length")
|
160
|
-
end
|
161
139
|
end
|
162
140
|
end
|