Skip to content

Commit b9accb4

Browse files
authored
Remove /html docs and redirect all pages to html.kitajs.org (#67)
1 parent 1f42b18 commit b9accb4

11 files changed

Lines changed: 93 additions & 1404 deletions

File tree

.vitepress/config.mts

Lines changed: 3 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -131,7 +131,7 @@ export default defineConfig({
131131
},
132132
{
133133
text: 'Html Engine',
134-
link: '../html/index.md'
134+
link: 'https://html.kitajs.org/'
135135
}
136136
],
137137

@@ -173,15 +173,15 @@ export default defineConfig({
173173
{ text: 'Serialization', link: 'serialization.md' },
174174
{ text: 'Exposing types', link: 'exposing-types.md' },
175175
{ text: 'JSDocs', link: 'jsdocs.md' },
176-
{ text: 'Html Engine', link: '../html/index.md' }
176+
{ text: 'Html Engine', link: 'https://html.kitajs.org/' }
177177
]
178178
},
179179
{
180180
text: 'Routing',
181181
base: '/routing/',
182182
items: [
183183
{ text: 'Rest Routes', link: 'index.md' },
184-
{ text: 'Html Routes', link: 'html.md' },
184+
{ text: 'Html Routes', link: 'https://html.kitajs.org/' },
185185
{ text: 'Configuration', link: 'configuration.md' }
186186
]
187187
},
@@ -240,21 +240,6 @@ export default defineConfig({
240240
{ text: 'Branding', link: 'branding.md' }
241241
]
242242
}
243-
],
244-
'/html/': [
245-
{
246-
base: '/html/',
247-
items: [
248-
{ text: 'Introduction', link: 'index.md' },
249-
{ text: 'Configuration', link: 'configuration.md' },
250-
{ text: 'Sanitization', link: 'sanitization.md' },
251-
{ text: 'Async Components', link: 'async.md' },
252-
{ text: 'Integrations', link: 'integrations.md' },
253-
{ text: 'JSX', link: 'jsx.md' },
254-
{ text: 'Deprecations', link: 'deprecations.md' },
255-
{ text: 'Benchmark', link: 'benchmark.md' }
256-
]
257-
}
258243
]
259244
},
260245

html/async.md

Lines changed: 9 additions & 282 deletions
Original file line numberDiff line numberDiff line change
@@ -1,284 +1,11 @@
1-
# Async
1+
---
2+
title: Redirecting...
3+
head:
4+
- - meta
5+
- http-equiv: refresh
6+
content: '0; url=https://html.kitajs.org/'
7+
---
28

3-
## Async await
9+
<script>if (typeof window !== 'undefined') window.location.replace('https://html.kitajs.org/')</script>
410

5-
`async`/`await` inside components are 100% supported.
6-
7-
When any child or sub child of a component tree is a `Promise<string>`, the
8-
whole tree will return a promise of html string.
9-
10-
If no async components are found, the result will be simply a string, and you
11-
can safely cast it into a string.
12-
13-
```tsx
14-
import assert from 'node:assert';
15-
import { setTimeout } from 'node:timers/promises';
16-
17-
async function Async() {
18-
await setTimeout(1000); // simulates work
19-
return <div>Async!</div>;
20-
}
21-
22-
function Sync() {
23-
return <div>Sync!</div>;
24-
}
25-
26-
const async = (
27-
<div>
28-
<Async />
29-
</div>
30-
);
31-
32-
assert(async instanceof Promise);
33-
34-
const sync = (
35-
<div>
36-
<Sync />
37-
</div>
38-
);
39-
40-
assert(typeof sync === 'string');
41-
```
42-
43-
A `JSX.Element` will always be a string. Once a children element is a async
44-
component, the entire upper tree will also be async.
45-
[Learn when JSX.Element is a Promise](#why-jsxelement-is-a-promise).
46-
47-
## Suspense component
48-
49-
The only problem when rendering templates is that you must wait for the whole
50-
template to be rendered before sending it to the client. This is not a problem
51-
for small templates, but it can be a problem for large templates.
52-
53-
To solve this problem, we provide a `Suspense` component that combined with
54-
`renderToStream()` rendering method, will stream a fallback component while it
55-
waits for his children to be rendered.
56-
57-
```tsx
58-
import { Suspense, renderToStream } from '@kitajs/html/suspense';
59-
60-
function renderUserPage(rid: number | string) {
61-
return (
62-
<Suspense
63-
rid={rid}
64-
fallback={<div>Loading username...</div>}
65-
catch={(err) => <div>Error: {String(err)}</div>}
66-
>
67-
<MyAsyncComponent />
68-
</Suspense>
69-
);
70-
}
71-
72-
// Html is a string readable stream that can be piped to the client
73-
const html = renderToStream(renderUserPage);
74-
```
75-
76-
<br />
77-
78-
<!-- > [!NOTE]
79-
> The `renderToStream()` is returns a native node/bun stream, head over to our
80-
> [suspense-server](./examples/suspense-server.tsx) example to see how to use it
81-
> with node:http, Express or Fastify servers. -->
82-
83-
<br />
84-
85-
The above example would render `<div>Loading username...</div>` while waiting
86-
for the `MyAsyncComponent` to be rendered.
87-
88-
When using `Suspense`, you cannot just call the component and get the html
89-
string, you need to use the `renderToStream` function to get a stream that can
90-
be piped to the client with updates. Otherwise, the fallback would render
91-
forever.
92-
93-
As the result of any JSX component is always a string, you must use the `rid`
94-
provided by `renderToStream` into all your suspense components, this way we can
95-
identify which suspense is for which request and be able to render concurrent
96-
requests.
97-
98-
Suspense also accepts async fallbacks, but it blocks rendering until the
99-
fallback is resolved.
100-
101-
```tsx
102-
import { Suspense } from '@kitajs/html/suspense';
103-
104-
function renderTemplate(rid: number | string) {
105-
return (
106-
<Suspense
107-
rid={rid}
108-
fallback={<MyAsyncFallback />}
109-
catch={(err) => <div>Error: {String(err)}</div>}
110-
>
111-
<MyAsyncComponent />
112-
</Suspense>
113-
);
114-
}
115-
```
116-
117-
The above example would only return anything after `MyAsyncFallback` is
118-
resolved. To catch async fallback errors, you must wrap it into a
119-
[`ErrorBoundary`](#error-boundaries).
120-
121-
<br />
122-
123-
## Error boundaries
124-
125-
The same way as promises must be awaited to resolve its own html, errors must be
126-
caught. Outside of [suspense](#suspense-component) components, you can use the
127-
provided error boundaries to catch errors.
128-
129-
```tsx
130-
import { ErrorBoundary } from '@kitajs/html/error-boundary';
131-
132-
function renderTemplate() {
133-
return (
134-
<ErrorBoundary catch={(err) => <div>Error: {String(err)}</div>}>
135-
<MyAsyncComponent />
136-
</ErrorBoundary>
137-
);
138-
}
139-
140-
// If MyAsyncComponent throws an error, it will render <div>Error: ...</div>
141-
const html = await renderTemplate();
142-
```
143-
144-
Error boundaries will only work for errors thrown inside async components, for
145-
sync components you must use `try`/`catch`.
146-
147-
```tsx
148-
function MySyncComponent() {
149-
try {
150-
const data = syncDbQuery();
151-
return <Username name={data.username} />;
152-
} catch (err) {
153-
return <div>Error: {String(err)}</div>;
154-
}
155-
}
156-
```
157-
158-
Error boundaries outside suspense components will only catch errors thrown by
159-
the fallback component. You must use the Suspense's `catch` property to handle
160-
errors thrown by its children components.
161-
162-
```tsx
163-
import { ErrorBoundary } from '@kitajs/html/error-boundary';
164-
import { renderToStream, Suspense } from '@kitajs/html/suspense';
165-
166-
function renderTemplate(rid: number | string) {
167-
return (
168-
<ErrorBoundary catch={<div>Only catches fallback errors</div>}>
169-
<Suspense
170-
rid={rid}
171-
fallback={<MyAsyncFallback />}
172-
catch={<div>Catches children errors</div>}
173-
>
174-
<MyAsyncComponent />
175-
</Suspense>
176-
</ErrorBoundary>
177-
);
178-
}
179-
180-
const html = renderToStream(renderTemplate);
181-
```
182-
183-
The above example would render `<div>Children error</div>` if `MyAsyncComponent`
184-
throws an error, or `<div>fallback error</div>` if `MyAsyncFallback` throws an
185-
error. If both throws an error, the first error will be changed to the second
186-
error as soon as the children error is thrown.
187-
188-
<br />
189-
190-
## `JSX.Element` might be a `Promise`?
191-
192-
> [!NOTE]
193-
>
194-
> Until [#14729](https://github.com/microsoft/TypeScript/issues/14729) gets
195-
> implemented, you need to manually cast `JSX.Element` into strings if you are
196-
> sure there is no inner async components in your component tree.
197-
198-
<br />
199-
200-
JSX elements are mostly strings everywhere.
201-
202-
However, as the nature of this package, once a children element is a async
203-
component, the entire upper tree will also be async. Unless you are sure that no
204-
other component in your entire codebase is async, you should always handle both
205-
string and promise cases.
206-
207-
```tsx
208-
// It may or may not have inner async components.
209-
const html = <MyAsyncComponent />;
210-
211-
if (html instanceof Promise) {
212-
// I'm a promise, I should be awaited
213-
console.log(await html);
214-
} else {
215-
// I'm a string, I can be used as is
216-
console.log(html);
217-
}
218-
```
219-
220-
## Api
221-
222-
### `renderToStream`
223-
224-
Transforms a component tree who may contain `Suspense` components into a stream
225-
of HTML.
226-
227-
There's two ways of using `renderToStream`:
228-
229-
With a `rid` parameter, to identify which suspense is for which request.
230-
231-
If you are using a framework or some kind of code that already generates a
232-
unique request id per request, just like
233-
[Fastify's request.id](https://fastify.dev/docs/latest/Reference/Request/), you
234-
can simply renders your component tree with it and pass it to `renderToStream`.
235-
236-
```tsx
237-
import { renderToStream } from '@kitajs/html/suspense';
238-
239-
// If you are literally doing this, please use the 2nd way XD
240-
let requestId = 0;
241-
242-
function handleRequest() {
243-
const rid = requestId++;
244-
const html = renderToStream(<LayoutWithSuspense rid={rid} />, rid);
245-
// pipe html to the client
246-
}
247-
```
248-
249-
If you do not have easy access to a unique request id, you can pass a callback
250-
as the first parameter to `renderToStream` that will be called with the request
251-
id.
252-
253-
```tsx
254-
import { renderToStream } from '@kitajs/html/suspense';
255-
256-
function handleRequest() {
257-
const html = renderToStream((rid) => <LayoutWithSuspense rid={rid} />);
258-
// pipe html to the client
259-
}
260-
```
261-
262-
### `renderToString`
263-
264-
Just like `renderToStream`, but only resolves when the whole tree is rendered.
265-
266-
::: warning
267-
268-
This method completely throws away the suspense feature, and will render the
269-
whole tree before returning the string.
270-
271-
This is only useful for testing environments or when you don't care about the
272-
time it takes to render the whole tree.
273-
274-
:::
275-
276-
```tsx
277-
import { renderToString } from '@kitajs/html/suspense';
278-
279-
async function handleRequest() {
280-
const html: string = await renderToString((rid) => (
281-
<LayoutWithSuspense rid={rid} />
282-
));
283-
}
284-
```
11+
This page has moved. Redirecting to [html.kitajs.org](https://html.kitajs.org/)...

0 commit comments

Comments
 (0)