Socket
Socket
Sign inDemoInstall

@ethicdevs/fastify-stream-react-views

Package Overview
Dependencies
12
Maintainers
1
Versions
103
Alerts
File Explorer

Advanced tools

Install Socket

Detect and block malicious and high-risk dependencies

Install

    @ethicdevs/fastify-stream-react-views

A fastify reply decorator to renderToMarkupStream a React component as a view/template (SSR, CSI/Islands)


Version published
Weekly downloads
12
increased by71.43%
Maintainers
1
Created
Weekly downloads
 

Readme

Source

@ethicdevs/fastify-stream-react-views

Built-in TypeScript definitions NPM MIT License

What started as a fastify reply decorator to renderToMarkupStream a React component as a view/template (plain-old fashioned SSR/monolith/PHP way, without CSR/hydration) is becoming a full-featured framework to build SSR/Islands based applications without the usual pain! 🚀


Looking for an SSR+Island ready solution?

Discover the React Monolith framework which is a framework we built on-top of this library so you don't have to! ⚡️

Sample usage for getting started quickly can be found in the the React Monolith samples repository


Installation

$ yarn add @ethicdevs/fastify-stream-react-views
# or
$ npm i @ethicdevs/fastify-stream-react-views

Usage

First create a server.ts file that will act as the application entry point.

// src/server.ts
import { join, resolve} from "path";
import fastify from "fastify";
import streamReactViews from "@ethicdevs/fastify-stream-react-views";

function main() {
  const app = fastify();

  // ... more fastify server setup ...

  app.register(streamReactViews, {
    appName: "YourAppName", // optional
    titleSeparatorChar: "∙", // optional
    commonProps: { // optional
      foo: 'bar',
      baz: 1,
    }
    islandsFolder: resolve(join(__dirname, 'islands'), // optional
    viewsFolder: resolve(join(__dirname, 'views'), // required
    viewContext: { // optional
      html: {
        dir: "ltr",
      },
      head: [
        { kind: "meta", charset: "utf-8" },
        {
          kind: "meta",
          name: "viewport",
          content: "width=device-width, initial-scale=1",
        },
        {
          kind: "link",
          rel: "icon",
          type: "image/x-icon",
          href: "/public/favicon.ico",
        },
      ],
    },
    withStyledSSR: true, // optional, set to true for styled-component usage
  });

  app.get('/', (_, reply) => {
    return reply.streamReactView('home', {
      title: "This will set the page title in tab bar!",
      hello: 'world',
      punctuation: '!'
    });
  });

  app.listen(...); // as usual
}

main();

Add an HomeView to test things works like this:

// src/views/HomeView.tsx
import type { ReactView } from "@ethicdevs/fastify-stream-react-views";
import React, { VFC } from "react";

import Counter from "../islands/Counter";

type HomeViewProps = {
  hello: string;
  punctuation?: "." | "!" | "?";
};

const HomeView: ReactView = ({ hello, punctuation }) => {
  return (
    <>
      <h1>{`Hello, ${hello}${punctuation || "!"}`}</h1>
      <Counter defaultValue={42} />
    </>
  );
};

export default HomeView;

Then the Counter Island so this component becomes interactive when page has loaded on the client-side (i.e. browser):

// src/islands/Counter.tsx
import type { ReactIsland } from "@ethicdevs/fastify-stream-react-views";
import React, { useState } from "react";

type CounterProps = {
  defaultValue?: number;
};

const Counter: ReactIsland<CounterProps> = ({ defaultValue = 0 }) => {
  const [counter, setCounter] = useState(defaultValue);
  const incrementCounter = () => setCounter((prev) => prev + 1);
  const decrementCounter = () => setCounter((prev) => prev - 1);
  return (
    <div>
      <strong aria-description={"Counter value"}>{`${counter}`}</strong>
      <button onClick={decrementCounter} title={"Decrement counter"}>
        -
      </button>
      <button onClick={incrementCounter} title={"Increment counter"}>
        +
      </button>
    </div>
  );
};

export default Counter;

Then navigate to the ip:port you listen to, and see the magic by inspecting both at the page source code level, as well as devtools/page inspector. Look how the generated HTML is neat and contains everything needed for the client to start being interactive in no-time (~6ms to be interactive in this example). Enjoy ;)

License

MIT

Keywords

FAQs

Last updated on 10 Dec 2023

Did you know?

Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.

Install

Related posts

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc