npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2024 – Pkg Stats / Ryan Hefner

@riotjs/ssr

v9.0.0

Published

Riot module to render riot components on the server

Downloads

240

Readme

ssr

Riot.js SSR logo

Riot module to render riot components on the server

Build Status

NPM version NPM downloads MIT License

Installation

npm i -S riot @riotjs/compiler @riotjs/ssr

Usage

render - to render only markup

You can simply render your components' markup as it follows:

import MyComponent from './my-component.js'
import render from '@riotjs/ssr'

const html = render('my-component', MyComponent, { some: 'initial props' })

Important If you want to import raw .riot components in your application you might want to use @riotjs/register

Note that components rendered on the server will always automatically receive the isServer=true property.

renderAsync - to handle asynchronous rendering

Components that can not be rendered synchronously must expose the onAsyncRendering method to the renderAsync function. For example:

<async-component>
  <p>{ state.username }<p>

  <script>
    export default {
      onBeforeMount({ isServer }) {
        // if it's not SSR we load the user data right the way
        if (!isServer) {
          this.loadUser()
        }
      },
      loadUser() {
        return fetch('/user/name').then(({name}) => {
          this.update({ name })
        })
      },
      // this function will be automatically called only
      // if the component is rendered via `renderAsync`
      onAsyncRendering() {
        return this.loadUser()
      }
    }
  </script>
</async-component>

The above component can be rendered on the server as it follows:

import MyComponent from './async-component.js'
import { renderAsync } from '@riotjs/ssr'

renderAsync('async-component', MyComponent, { some: 'initial props' }).then(
  (html) => {
    console.log(html)
  },
)

Notice that the onAsyncRendering can either return a promise or use the resolve, reject callbacks:

export default {
  // this is ok
  async onAsyncRendering() {
    await loadData()
  },
}
export default {
  // this is also ok
  onAsyncRendering(resolve, reject) {
    setTimeout(resolve, 1000)
  },
}

IMPORTANT nested onAsyncRendering on children components are not supported!

fragments - to render html and css

You can also extract the rendered html and css separately using the fragments function:

import MyComponent from './my-component.js'
import { fragments } from '@riotjs/ssr'

const { html, css } = fragments('my-component', MyComponent, {
  some: 'initial props',
})

renderAsyncFragments - to handle asynchronous fragments rendering

It works like the method above but asynchronously

Advanced tips

If you want to render your whole document you can simply pass html as name of your root node. For example

<html>
    <head>
        <title>{ state.message }</title>
        <meta each={ meta in state.meta } {...meta}/>
    </head>

    <body>
        <p>{ state.message }</p>
        <script src='path/to/a/script.js'></script>
    </body>

    <script>
        export default {
          state: {
            message: 'hello',
            meta: [{
              name: 'description',
              content: 'a description'
            }]
          }
        }
    </script>
</html>

It can be rendered as it follows:

import MyRootApplication from './my-root-application.js'
import render from '@riotjs/ssr'

const html = render('html', MyRootApplication)

Better SSR control using the createRenderer

For a better control over your HTML rendering you might want to use the createRenderer factory function. This method allows the creation of a rendering function receiving the {getHTML, css, dispose, element} option object.

  • getHTML: give you the rendered html of your component as string
  • css: the css of your component as string
  • dispose: clean the memory used on the server needed to render your component
  • element: the component instance you are mounting

For example

import MyComponent from './my-component.js'
import { createRenderer } from '@riotjs/ssr'

const logRendrer = createRenderer(({ getHTML, getCSS, dispose, component }) => {
  const html = getHTML()
  const css = getCSS()

  console.log('Rendering the component: %s', component.name)

  dispose()
  return { html, css }
})

// use your logRenderer
const { html, css } = logRendrer('my-component', MyComponent, {
  some: 'initial props',
})

DOM Globals

@riotjs/ssr needs DOM globals (like window, document ...) to properly render your markup. With the domGlobals exported object you can decide manually when the globals should be created and deleted from in your node applications.

import { domGlobals } from '@riotjs/ssr'

domGlobals.create()

// global DOM object in your node environement are now defined
console.log(global.window, global.document)

// they will be cleared and will be undefined
domGlobals.clear()

Caveat

If you are rendering your whole HTML you will not be able to use multiple times the inline <script> <style> tags. Of course, you can use only once the ones used by Riot.js to customize your components. For example:

<html>
    <head>
        <!-- allowed -->
        <script src='path/to/some/script.js'></script>

        <!-- not allowed -->
        <style>
        </style>

        <!-- not allowed -->
        <script>
            const globalstuff = {}
        </script>
    </head>

    <body>
        <!-- application html -->
    </body>

    <!-- allowed -->
    <script>
        export default {
            // app code
        }
    </script>

    <!-- allowed -->
    <style>
        :host {}
    </style>
</html>