Skip to content

Commit

Permalink
[fix] hydrate validation errors
Browse files Browse the repository at this point in the history
Fixes #5906
  • Loading branch information
dummdidumm committed Aug 16, 2022
1 parent 278770b commit f768ac4
Show file tree
Hide file tree
Showing 7 changed files with 65 additions and 5 deletions.
5 changes: 5 additions & 0 deletions .changeset/angry-peaches-warn.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
'@sveltejs/kit': patch
---

Hydration validation errors
20 changes: 16 additions & 4 deletions packages/kit/src/runtime/client/client.js
Original file line number Diff line number Diff line change
Expand Up @@ -389,6 +389,7 @@ export function create_client({ target, session, base, trailing_slash }) {
* status: number;
* error: HttpError | Error | null;
* routeId: string | null;
* validation_errors?: string | undefined;
* }} opts
*/
async function get_navigation_result_from_branch({
Expand All @@ -397,7 +398,8 @@ export function create_client({ target, session, base, trailing_slash }) {
branch,
status,
error,
routeId
routeId,
validation_errors
}) {
const filtered = /** @type {import('./types').BranchNode[] } */ (branch.filter(Boolean));

Expand All @@ -412,7 +414,8 @@ export function create_client({ target, session, base, trailing_slash }) {
session_id
},
props: {
components: filtered.map((branch_node) => branch_node.node.component)
components: filtered.map((branch_node) => branch_node.node.component),
errors: validation_errors
}
};

Expand Down Expand Up @@ -1211,8 +1214,16 @@ export function create_client({ target, session, base, trailing_slash }) {
let result;

try {
const script = document.querySelector(`script[sveltekit\\:data-type="server_data"]`);
const server_data = script?.textContent ? JSON.parse(script.textContent) : [];
/**
* @param {string} type
* @param {any} fallback
*/
const parse = (type, fallback) => {
const script = document.querySelector(`script[sveltekit\\:data-type="${type}"]`);
return script?.textContent ? JSON.parse(script.textContent) : fallback;
};
const server_data = parse('server_data', []);
const validation_errors = parse('validation_errors', undefined);

const branch_promises = node_ids.map(async (n, i) => {
return load_node({
Expand Down Expand Up @@ -1243,6 +1254,7 @@ export function create_client({ target, session, base, trailing_slash }) {
error.message
)
: error,
validation_errors,
routeId
});
} catch (e) {
Expand Down
6 changes: 6 additions & 0 deletions packages/kit/src/runtime/server/page/render.js
Original file line number Diff line number Diff line change
Expand Up @@ -266,6 +266,12 @@ export async function render_response({
);
}

if (validation_errors) {
serialized_data.push(
render_json_payload_script({ type: 'validation_errors' }, validation_errors)
);
}

body += `\n\t${serialized_data.join('\n\t')}`;
}

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
export const POST = async () => {
return {
errors: {
message: 'an error occurred'
}
};
};
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
<script>
import { browser } from '$app/env';
export let errors
const hydrated_error_message = browser ? 'hydrated: ' + errors?.message : '';
</script>
<form method="post">
<button type="submit">Submit</button>
</form>
<p class="server">{errors?.message}</p>
<!-- needs to be like this else the selector is found too soon (before hydration) -->
{#if hydrated_error_message}
<p class="client">{hydrated_error_message}</p>
{/if}
11 changes: 11 additions & 0 deletions packages/kit/test/apps/basics/test/test.js
Original file line number Diff line number Diff line change
Expand Up @@ -1717,3 +1717,14 @@ test.describe('XSS', () => {
);
});
});

test.describe('Actions', () => {
test('Error props are returned', async ({ page, javaScriptEnabled }) => {
await page.goto('/actions/form-errors');
await page.click('button');
expect(await page.textContent('p.server')).toBe('an error occurred');
if (javaScriptEnabled) {
expect(await page.textContent('p.client')).toBe('hydrated: an error occurred');
}
});
});
3 changes: 2 additions & 1 deletion packages/kit/types/internal.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -141,7 +141,8 @@ export interface PageData {

export type PayloadScriptAttributes =
| { type: 'data'; url: string; body?: string }
| { type: 'server_data' };
| { type: 'server_data' }
| { type: 'validation_errors' };

export interface PrerenderDependency {
response: Response;
Expand Down

0 comments on commit f768ac4

Please sign in to comment.