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
9 changes: 7 additions & 2 deletions e2e/fixtures/ssr-basic/src/components/Counter.tsx
Original file line number Diff line number Diff line change
@@ -1,16 +1,21 @@
'use client';

import { useState } from 'react';
import { useId, useState } from 'react';

export const Counter = () => {
const [count, setCount] = useState(0);
const id = useId();
return (
<div
data-testid="counter"
style={{ border: '3px blue dashed', margin: '1em', padding: '1em' }}
>
<p data-testid="count">{count}</p>
<button data-testid="increment" onClick={() => setCount((c) => c + 1)}>
<button
id={id}
data-testid="increment"
onClick={() => setCount((c) => c + 1)}
>
Increment
</button>
</div>
Expand Down
12 changes: 12 additions & 0 deletions e2e/ssr-basic.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -58,5 +58,17 @@
await page.close();
await context.close();
});

test('check hydration error', async ({ page }) => {
test.skip(mode !== 'DEV');
const messages: string[] = [];
page.on('console', (msg) => messages.push(msg.text()));
await page.goto(`http://localhost:${port}/`);
await expect(page.getByTestId('app-name')).toHaveText('Waku');
await expect(page.getByTestId('count')).toHaveText('0');
await page.getByTestId('increment').click();
await expect(page.getByTestId('count')).toHaveText('1');

Check failure on line 70 in e2e/ssr-basic.spec.ts

View workflow job for this annotation

GitHub Actions / E2E on ubuntu-latest (Node 18.17.0) - (3/4)

[firefox] › ssr-basic.spec.ts:62:5 › ssr-basic: DEV › check hydration error

1) [firefox] › ssr-basic.spec.ts:62:5 › ssr-basic: DEV › check hydration error ─────────────────── Error: Timed out 10000ms waiting for expect(locator).toHaveText(expected) Locator: getByTestId('count') Expected string: "1" Received string: "0" Call log: - expect.toHaveText with timeout 10000ms - waiting for getByTestId('count') 14 × locator resolved to <p data-testid="count">0</p> - unexpected value "0" 68 | await expect(page.getByTestId('count')).toHaveText('0'); 69 | await page.getByTestId('increment').click(); > 70 | await expect(page.getByTestId('count')).toHaveText('1'); | ^ 71 | expect(messages.join('\n')).not.toContain('hydration-mismatch'); 72 | }); 73 | }); at /home/runner/work/waku/waku/e2e/ssr-basic.spec.ts:70:47

Check failure on line 70 in e2e/ssr-basic.spec.ts

View workflow job for this annotation

GitHub Actions / E2E on ubuntu-latest (Node 22.7.0) - (3/4)

[firefox] › ssr-basic.spec.ts:62:5 › ssr-basic: DEV › check hydration error

1) [firefox] › ssr-basic.spec.ts:62:5 › ssr-basic: DEV › check hydration error ─────────────────── Error: Timed out 10000ms waiting for expect(locator).toHaveText(expected) Locator: getByTestId('count') Expected string: "1" Received string: "0" Call log: - expect.toHaveText with timeout 10000ms - waiting for getByTestId('count') 14 × locator resolved to <p data-testid="count">0</p> - unexpected value "0" 68 | await expect(page.getByTestId('count')).toHaveText('0'); 69 | await page.getByTestId('increment').click(); > 70 | await expect(page.getByTestId('count')).toHaveText('1'); | ^ 71 | expect(messages.join('\n')).not.toContain('hydration-mismatch'); 72 | }); 73 | }); at /home/runner/work/waku/waku/e2e/ssr-basic.spec.ts:70:47

Check failure on line 70 in e2e/ssr-basic.spec.ts

View workflow job for this annotation

GitHub Actions / E2E on ubuntu-latest (Node 20.8.0) - (1/4)

[chromium] › ssr-basic.spec.ts:62:5 › ssr-basic: DEV › check hydration error

1) [chromium] › ssr-basic.spec.ts:62:5 › ssr-basic: DEV › check hydration error ────────────────── Error: Timed out 10000ms waiting for expect(locator).toHaveText(expected) Locator: getByTestId('count') Expected string: "1" Received string: "0" Call log: - expect.toHaveText with timeout 10000ms - waiting for getByTestId('count') 14 × locator resolved to <p data-testid="count">0</p> - unexpected value "0" 68 | await expect(page.getByTestId('count')).toHaveText('0'); 69 | await page.getByTestId('increment').click(); > 70 | await expect(page.getByTestId('count')).toHaveText('1'); | ^ 71 | expect(messages.join('\n')).not.toContain('hydration-mismatch'); 72 | }); 73 | }); at /home/runner/work/waku/waku/e2e/ssr-basic.spec.ts:70:47
expect(messages.join('\n')).not.toContain('hydration-mismatch');
});
});
}
8 changes: 0 additions & 8 deletions packages/waku/src/lib/plugins/vite-plugin-rsc-index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,6 @@ import type { Plugin } from 'vite';

import { SRC_MAIN } from '../constants.js';

// This should be consistent with the one in renderers/html.ts
const DEFAULT_HTML_HEAD = `
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<meta name="generator" content="Waku" />
`.trim();

export function rscIndexPlugin(opts: {
basePath: string;
srcDir: string;
Expand All @@ -19,7 +12,6 @@ export function rscIndexPlugin(opts: {
<!doctype html>
<html>
<head>
${DEFAULT_HTML_HEAD}
</head>
<body>
<script src="${opts.basePath}${opts.srcDir}/${SRC_MAIN}" async type="module"></script>
Expand Down
11 changes: 0 additions & 11 deletions packages/waku/src/lib/renderers/html.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,16 +14,6 @@ import { renderRsc, renderRscElement, getExtractFormState } from './rsc.js';
// TODO move types somewhere
import type { HandlerContext } from '../middleware/types.js';

// This should be consistent with the one in vite-plugin-rsc-index.ts
const DEFAULT_HTML_HEAD = [
createElement('meta', { charSet: 'utf-8' }),
createElement('meta', {
name: 'viewport',
content: 'width=device-width, initial-scale=1',
}),
createElement('meta', { name: 'generator', content: 'Waku' }),
];

type Elements = Record<string, ReactNode>;

const fakeFetchCode = `
Expand Down Expand Up @@ -229,7 +219,6 @@ export async function renderHtml(
Omit<ComponentProps<typeof ServerRoot>, 'children'>
>,
{ elements: elementsPromise },
...DEFAULT_HTML_HEAD,
htmlNode as any,
),
{
Expand Down
24 changes: 22 additions & 2 deletions packages/waku/src/minimal/client.ts
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,15 @@ declare global {
}
}

const DEFAULT_HTML_HEAD = [
createElement('meta', { charSet: 'utf-8' }),
createElement('meta', {
name: 'viewport',
content: 'width=device-width, initial-scale=1',
}),
createElement('meta', { name: 'generator', content: 'Waku' }),
];

const BASE_PATH = `${import.meta.env?.WAKU_CONFIG_BASE_PATH}${
import.meta.env?.WAKU_CONFIG_RSC_BASE
}/`;
Expand Down Expand Up @@ -231,7 +240,12 @@ export const Root = ({
return createElement(
RefetchContext.Provider,
{ value: refetch },
createElement(ElementsContext.Provider, { value: elements }, children),
createElement(
ElementsContext.Provider,
{ value: elements },
...DEFAULT_HTML_HEAD,
children,
),
);
};

Expand Down Expand Up @@ -376,4 +390,10 @@ export const ServerRootInternal = ({
}: {
elements: Elements;
children: ReactNode;
}) => createElement(ElementsContext.Provider, { value: elements }, children);
}) =>
createElement(
ElementsContext.Provider,
{ value: elements },
...DEFAULT_HTML_HEAD,
children,
);
Loading