diff --git a/mod.ts b/mod.ts
index 93c6db3..2954a8e 100644
--- a/mod.ts
+++ b/mod.ts
@@ -9,6 +9,7 @@ export type { Extension } from './extensions.ts'
export { default as jwt } from './jwt.ts'
export { LocationData } from './location_data.ts'
export { otp } from './otp.ts'
+export { h, Renderer } from './render.ts'
export { sendMail } from './send_mail.ts'
export { Store } from './store.ts'
diff --git a/render.ts b/render.ts
new file mode 100644
index 0000000..2b11b8b
--- /dev/null
+++ b/render.ts
@@ -0,0 +1,58 @@
+// Copyright 2023 Samuel Kopp. All rights reserved. Apache-2.0 license.
+import { brightYellow, gray } from 'https://deno.land/std@0.198.0/fmt/colors.ts'
+import {
+ defineConfig,
+ extract,
+ install,
+} from 'https://esm.sh/@twind/core@1.1.3'
+import presetAutoPrefix from 'https://esm.sh/@twind/preset-autoprefix@1.0.7'
+import presetTailwind from 'https://esm.sh/@twind/preset-tailwind@1.1.4'
+import { default as renderToString } from 'https://esm.sh/preact-render-to-string@6.1.0?deps=preact@10.17.1&target=es2022'
+import { VNode } from 'https://esm.sh/preact@10.17.1?target=es2022'
+import { Context } from './mod.ts'
+
+export function render(c: Context, Component: VNode) {
+ const htmlString = renderToString(Component)
+
+ try {
+ const { html, css } = extract(htmlString) // twind throws error when trying to extract if it is not installed
+
+ c.res.body = `
${html}`
+ } catch (_err) {
+ if (c.dev) {
+ console.warn(
+ gray(
+ `${
+ brightYellow('warning')
+ } - twind is not installed, thus styles might not be applied`,
+ ),
+ )
+ }
+
+ c.res.body = htmlString
+ }
+
+ c.res.header('content-type', 'text/html; charset=utf-8')
+}
+
+export class Renderer {
+ render
+
+ constructor(options?: Parameters[0]) {
+ if (options) {
+ options.presets = options.presets
+ ? [presetAutoPrefix(), presetTailwind(), ...options.presets]
+ : [presetAutoPrefix(), presetTailwind()]
+ }
+
+ install(defineConfig(
+ options ?? {
+ presets: [presetAutoPrefix(), presetTailwind()],
+ },
+ ))
+
+ this.render = render
+ }
+}
+
+export { h } from 'https://esm.sh/preact@10.17.1?target=es2022'
diff --git a/render.tsx b/render.tsx
deleted file mode 100644
index 741a6c7..0000000
--- a/render.tsx
+++ /dev/null
@@ -1,23 +0,0 @@
-// Copyright 2023 Samuel Kopp. All rights reserved. Apache-2.0 license.
-/** @jsx h */
-import { default as renderToString } from 'https://esm.sh/preact-render-to-string@6.1.0?deps=preact@10.16.0'
-import { h, VNode } from 'https://esm.sh/preact@10.17.0'
-import { extract } from 'https://esm.sh/@twind/core@1.1.3'
-
-import { Context } from './mod.ts'
-
-export function render(c: Context, Component: (() => h.JSX.Element) | VNode) {
- const html$ = renderToString(
- Component instanceof Function ? : Component,
- )
- try {
- const { html, css } = extract(html$) // twind throws error when trying to extract if it is not installed
- c.res.body = `${html}`
- } catch (e) {
- console.warn('twind is not installed, styles might not be applied')
- c.res.body = html$
- }
- c.res.header('content-type', 'text/html; charset=utf-8')
-}
-
-export { h } from 'https://esm.sh/preact@10.17.0'
diff --git a/test/deps.ts b/test/deps.ts
index f642d71..44d2a13 100644
--- a/test/deps.ts
+++ b/test/deps.ts
@@ -3,10 +3,5 @@ export {
assertEquals,
assertInstanceOf,
} from 'https://deno.land/std@0.198.0/assert/mod.ts'
-export { z } from 'https://deno.land/x/zod@v3.21.4/mod.ts'
-export { defineConfig } from 'https://esm.sh/@twind/core@1.1.3'
-import presetAutoPrefix from 'https://esm.sh/@twind/preset-autoprefix@1.0.7'
-import presetTailwind from 'https://esm.sh/@twind/preset-tailwind@1.1.4'
-export { presetAutoPrefix, presetTailwind }
export { DOMParser } from 'https://deno.land/x/deno_dom@v0.1.38/deno-dom-wasm.ts'
-export { install } from 'https://esm.sh/@twind/core@1.1.3'
+export { z } from 'https://deno.land/x/zod@v3.21.4/mod.ts'
diff --git a/test/render.test.tsx b/test/render.test.tsx
index 219e3c2..92c071d 100644
--- a/test/render.test.tsx
+++ b/test/render.test.tsx
@@ -1,23 +1,12 @@
// Copyright 2023 Samuel Kopp. All rights reserved. Apache-2.0 license.
/** @jsx h */
-
-import { h, render } from '../render.tsx'
-import cheetah from '../mod.ts'
-import {
- assert,
- assertEquals,
- defineConfig,
- DOMParser,
- install,
- presetAutoPrefix,
- presetTailwind,
-} from './deps.ts'
+import cheetah, { h, Renderer } from '../mod.ts'
+import { assert, assertEquals, DOMParser } from './deps.ts'
Deno.test('render', async () => {
const app = new cheetah()
- install(defineConfig({
- presets: [presetAutoPrefix(), presetTailwind()],
- }))
+
+ const { render } = new Renderer()
function Styled() {
return (
@@ -27,12 +16,14 @@ Deno.test('render', async () => {
)
}
- app.get('/a', (c) => render(c, Styled))
+ app.get('/a', (c) => render(c, ))
const a = await app.fetch(new Request('http://localhost/a'))
+ const tx = await a.text()
+
const document = new DOMParser().parseFromString(
- await a.text(),
+ tx,
'text/html',
)