Fix a hydration mismatch in output that starts with a blank line
The HTML parser drops a newline right after <pre>'s opening tag, so check output beginning with one (cargo test -q's does) rendered differently in the browser than on the server. Output now sits in a <code> inside the <pre>, where the newline survives. A client entry logs any future mismatch with the component it happened in.
5 files+29−60/5 viewed
| 102 | 102 | )} | |
| 103 | 103 | </summary> | |
| 104 | 104 | <pre className="max-h-72 overflow-auto border-t border-line p-2.5 font-mono text-[0.6875rem] leading-relaxed whitespace-pre-wrap text-muted"> | |
| 105 | − | {result.output || "No output."} | |
| 106 | − | {result.exitCode != null && result.exitCode !== 0 && `\n\nExit code ${result.exitCode}.`} | |
| 105 | + | {/* In a <code>: a newline right after <pre> is dropped by | |
| 106 | + | the HTML parser, and the page would differ from React's. */} | |
| 107 | + | <code> | |
| 108 | + | {result.output || "No output."} | |
| 109 | + | {result.exitCode != null && result.exitCode !== 0 && `\n\nExit code ${result.exitCode}.`} | |
| 110 | + | </code> | |
| 107 | 111 | </pre> | |
| 108 | 112 | </details> | |
| 109 | 113 | </li> |
| 138 | 138 | base={`/${repo.namespace}/${repo.name}/blob/${ref}${path ? `/${path}` : ""}`} | |
| 139 | 139 | /> | |
| 140 | 140 | ) : ( | |
| 141 | − | <pre className="whitespace-pre-wrap text-sm">{readme.text}</pre> | |
| 141 | + | <pre className="whitespace-pre-wrap text-sm"><code>{readme.text}</code></pre> | |
| 142 | 142 | )} | |
| 143 | 143 | </div> | |
| 144 | 144 | </section> | |
| 226 | 226 | > | |
| 227 | 227 | {lines.map((_, i) => i + 1).join("\n")} | |
| 228 | 228 | </pre> | |
| 229 | − | <pre className="pr-4 pl-5">{lines.join("\n")}</pre> | |
| 229 | + | <pre className="pr-4 pl-5"><code>{lines.join("\n")}</code></pre> | |
| 230 | 230 | </div> | |
| 231 | 231 | ) : ( | |
| 232 | 232 | <p className="p-6 text-sm text-muted"> |
| 1 | + | import { StrictMode, startTransition } from "react"; | |
| 2 | + | import { hydrateRoot } from "react-dom/client"; | |
| 3 | + | import { HydratedRouter } from "react-router/dom"; | |
| 4 | + | ||
| 5 | + | startTransition(() => { | |
| 6 | + | hydrateRoot( | |
| 7 | + | document, | |
| 8 | + | <StrictMode> | |
| 9 | + | <HydratedRouter /> | |
| 10 | + | </StrictMode>, | |
| 11 | + | { | |
| 12 | + | // React recovers from a page the server rendered differently by | |
| 13 | + | // rendering it again here; say where, so it can be fixed. | |
| 14 | + | onRecoverableError(error, info) { | |
| 15 | + | console.error("g1t: recovered from", error, info.componentStack); | |
| 16 | + | }, | |
| 17 | + | }, | |
| 18 | + | ); | |
| 19 | + | }); |
| 238 | 238 | </span> | |
| 239 | 239 | </summary> | |
| 240 | 240 | <pre className="overflow-x-auto border-t border-line p-3 font-mono text-xs whitespace-pre-wrap text-muted"> | |
| 241 | − | {entry.text} | |
| 241 | + | <code>{entry.text}</code> | |
| 242 | 242 | </pre> | |
| 243 | 243 | </details> | |
| 244 | 244 | ) : ( |
| 135 | 135 | .map((result) => ( | |
| 136 | 136 | <details key={result.command} className="mt-2"> | |
| 137 | 137 | <summary className="cursor-pointer font-mono text-xs text-danger">{result.command}</summary> | |
| 138 | − | <pre className="mt-1.5 max-h-48 overflow-auto rounded-lg bg-bg p-3 text-xs text-muted">{result.output}</pre> | |
| 138 | + | <pre className="mt-1.5 max-h-48 overflow-auto rounded-lg bg-bg p-3 text-xs text-muted"><code>{result.output}</code></pre> | |
| 139 | 139 | </details> | |
| 140 | 140 | ))} | |
| 141 | 141 | </div> |