Skip to content

Commit

Permalink
feat: add renderToString function (#1971)
Browse files Browse the repository at this point in the history
It is now possible to use `renderToString` to test the SSR rendering of a component.

To do so, use `renderToString(MyComponent)`.
`renderToString` returns a `Promise<string>` with the HTML rendered.

```ts
  it('returns correct html with pre-fetched data on server', async () => {
    const Component = defineComponent({
      template: '<div>{{ text }}</div>',
      setup() {
        const text = ref<string | null>(null)
        onServerPrefetch(async () => {
          text.value = await fakeFetch('onServerPrefetch')
        })
        return { text }
      }
    })

    const contents = await renderToString(Component)

    expect(contents).toBe('<div>onServerPrefetch</div>')
  })
```

Co-authored-by: Robert Soriano <sorianorobertc@gmail.com>
  • Loading branch information
cexbrayat and wobsoriano committed Feb 19, 2023
1 parent 5761413 commit 2aea499
Show file tree
Hide file tree
Showing 11 changed files with 815 additions and 370 deletions.
3 changes: 2 additions & 1 deletion docs/.vitepress/config.ts
Expand Up @@ -93,7 +93,8 @@ export default defineConfig({
{
text: 'Stubs and Shallow Mount',
link: '/guide/advanced/stubs-shallow-mount'
}
},
{ text: 'Server-side rendering', link: '/guide/advanced/ssr' }
]
},
{
Expand Down
42 changes: 42 additions & 0 deletions docs/guide/advanced/ssr.md
@@ -0,0 +1,42 @@
# Testing Server-side Rendering

Vue Test Utils provides `renderToString` to test Vue applications that use server-side rendering (SSR).
This guide will walk you through the process of testing a Vue application that uses SSR.

## `renderToString`

`renderToString` is a function that renders a Vue component to a string.
It is an asynchronous function that returns a Promise,
and accepts the same parameters as `mount` or `shallowMount`.

Let's consider a simple component that uses the `onServerPrefetch` hook:

```ts
function fakeFetch(text: string) {
return Promise.resolve(text)
}

const Component = defineComponent({
template: '<div>{{ text }}</div>',
setup() {
const text = ref<string | null>(null)

onServerPrefetch(async () => {
text.value = await fakeFetch('onServerPrefetch')
})

return { text }
}
})
```

You can write a test for this component using `renderToString`:

```ts
import { renderToString } from '@vue/test-utils'

it('renders the value returned by onServerPrefetch', async () => {
const contents = await renderToString(Component)
expect(contents).toBe('<div>onServerPrefetch</div>')
})
```
5 changes: 4 additions & 1 deletion package.json
Expand Up @@ -40,6 +40,7 @@
"@vue/compat": "3.2.47",
"@vue/compiler-dom": "3.2.47",
"@vue/compiler-sfc": "3.2.47",
"@vue/server-renderer": "3.2.47",
"c8": "7.12.0",
"eslint": "8.34.0",
"eslint-config-prettier": "8.6.0",
Expand All @@ -65,10 +66,12 @@
},
"peerDependencies": {
"@vue/compiler-dom": "^3.0.1",
"@vue/server-renderer": "^3.0.1",
"vue": "^3.0.1"
},
"optionalDependencies": {
"@vue/compiler-dom": "^3.0.1"
"@vue/compiler-dom": "^3.0.1",
"@vue/server-renderer": "^3.0.1"
},
"author": {
"name": "Lachlan Miller",
Expand Down
17 changes: 2 additions & 15 deletions pnpm-lock.yaml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

8 changes: 6 additions & 2 deletions rollup.config.ts
Expand Up @@ -25,7 +25,10 @@ function createEntry(options) {
'vue',
isEsmBrowser
? '@vue/compiler-dom/dist/compiler-dom.esm-browser'
: '@vue/compiler-dom'
: '@vue/compiler-dom',
isEsmBrowser
? '@vue/server-renderer/dist/compiler-dom.esm-browser'
: '@vue/server-renderer'
],
plugins: [
replace({
Expand All @@ -47,7 +50,8 @@ function createEntry(options) {
format,
globals: {
vue: 'Vue',
'@vue/compiler-dom': 'VueCompilerDOM'
'@vue/compiler-dom': 'VueCompilerDOM',
'@vue/server-renderer': 'VueServerRenderer'
}
}
}
Expand Down

0 comments on commit 2aea499

Please sign in to comment.