Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 3 additions & 1 deletion src/routes/(5)guides/(6)data-fetching-patterns.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -196,7 +196,9 @@ function OrderHistory() {
return (
<Loading fallback={<TableSkeleton />}>
<table class={{ stale: isPending(() => orders.length) }}>
<For each={orders}>{(order) => <OrderRow order={order} />}</For>
<tbody>
<For each={orders}>{(order) => <OrderRow order={order} />}</For>
</tbody>
</table>
<Pager page={latest(page)} onChange={setPage} />
</Loading>
Expand Down
20 changes: 20 additions & 0 deletions src/routes/(5)guides/(8)ssr-safe-code.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -288,6 +288,26 @@ The compiler cannot see across components.
A `Description` component that renders `<p>{props.children}</p>` and a parent that passes `<div>` children each compile to a valid template, and the browser still rebuilds the tree at runtime.
When a hydration warning points at an element whose parent in the Elements panel is not the parent in the JSX, look for nesting that spans a component boundary and fix the outer element.

Table rows are the common case.
A `<table>` whose rows come from a `<For>` or a row component holds no `<tr>` in its own template, so the build passes, and the parser still moves the server's rows into a `<tbody>` it adds.
The list then cannot update those rows after hydration: a removed row stays and a new row lands after the `<tbody>`.
Development warns `TABLE_ROWS_WITHOUT_TBODY` once for each such table.
Write the `<tbody>` yourself:

```tsx
// Avoid: the parser wraps the server's rows in an implied <tbody>
<table>
<For each={orders()}>{(order) => <OrderRow order={order} />}</For>
</table>;

// Prefer: the <tbody> is part of the template
<table>
<tbody>
<For each={orders()}>{(order) => <OrderRow order={order} />}</For>
</tbody>
</table>;
```

## Reading the hydration warnings

Development prints one of five messages when the server's DOM and the client's expectations diverge.
Expand Down
Loading