@react-ssr/express-engine-jsx v0.1.145
Overview
- SSR (Server Side Rendering) as a view template engine
- Passing the server data to the client
props
- Dynamic
props
without caring about SSR- Suitable for dynamic routes like blogging
- Dynamic
Head
component - HMR when
process.env.NODE_ENV !== 'production'
Usage
With @react-ssr/express
Install it:
$ npm install --save @react-ssr/express express react react-dom
And add a script to your package.json like this:
{
"scripts": {
"start": "node server.js"
}
}
Populate files below inside your project:
./.babelrc
{
"presets": [
"@react-ssr/express/babel"
]
}
./server.js
const express = require('express');
const register = require('@react-ssr/express/register');
const app = express();
(async () => {
// register `.jsx` or `.tsx` as a view template engine
await register(app);
app.get('/', (req, res) => {
const message = 'Hello World!';
res.render('index', { message });
});
app.listen(3000, () => {
console.log('> Ready on http://localhost:3000');
});
})();
./views/index.jsx
export default function Index({ message }) {
return <p>{message}</p>;
}
Then just run npm start
and go to http://localhost:3000
.
You'll see Hello World!
.
With @react-ssr/nestjs-express
Install it:
# install NestJS dependencies
$ npm install --save @nestjs/core @nestjs/common @nestjs/platform-express
# install @react-ssr/nestjs-express
$ npm install --save @react-ssr/nestjs-express react react-dom
And add a script to your package.json like this:
{
"scripts": {
"start": "ts-node --project tsconfig.server.json server/main.ts"
}
}
Populate files below inside your project:
./.babelrc
{
"presets": [
"@react-ssr/nestjs-express/babel"
]
}
./tsconfig.json
{
"compilerOptions": {
"target": "esnext",
"module": "esnext",
"moduleResolution": "node",
"jsx": "preserve",
"lib": [
"dom",
"dom.iterable",
"esnext"
],
"strict": true,
"allowJs": true,
"skipLibCheck": true,
"esModuleInterop": true,
"isolatedModules": true,
"resolveJsonModule": true,
"emitDecoratorMetadata": true,
"experimentalDecorators": true
},
"exclude": [
"node_modules",
".ssr"
]
}
./tsconfig.server.json
{
"extends": "./tsconfig.json",
"compilerOptions": {
"module": "commonjs"
},
"include": [
"server"
]
}
./server/main.ts
import { NestFactory } from '@nestjs/core';
import { NestExpressApplication } from '@nestjs/platform-express';
import register from '@react-ssr/nestjs-express/register';
import { AppModule } from './app.module';
async function bootstrap() {
const app = await NestFactory.create<NestExpressApplication>(AppModule);
// register `.tsx` as a view template engine
await register(app);
app.listen(3000, async () => {
console.log(`> Ready on http://localhost:3000`);
});
}
bootstrap();
./server/app.module.ts
import { Module } from '@nestjs/common';
import { AppController } from './app.controller';
@Module({
controllers: [
AppController,
],
})
export class AppModule {}
./server/app.controller.ts
import {
Controller,
Get,
Render,
} from '@nestjs/common';
@Controller()
export class AppController {
@Get()
@Render('index') // this will render `views/index.tsx`
public showHome() {
const user = { name: 'NestJS' };
return { user };
}
}
./views/index.tsx
interface IndexProps {
user: any;
}
const Index = ({ user }: IndexProps) => {
return <p>Hello {user.name}!</p>;
};
export default Index;
Then just run npm start
and go to http://localhost:3000
, you'll see Hello NestJS!
.
Configuration (ssr.config.js
)
Here is the default ssr.config.js
, which is used by react-ssr
when there are no valid values:
module.exports = {
id: 'default',
viewsDir: 'views',
distDir: '.ssr',
webpack: (config /* webpack.Configuration */, env /* 'development' | 'production' */) => {
return config;
},
};
ssr.config.js#id
The id of UI framework. (default: default
)
It can be ignored only when the project does not use any UI frameworks.
Supported UI frameworks are:
- emotion
- styled-components
- material-ui
- antd
- and more...
For example, if we want to use emotion
, ssr.config.js
is like this:
module.exports = {
id: 'emotion',
};
ssr.config.js#viewsDir
The place where we put views. (default: views
)
A function res.render('xxx')
will render views/xxx.jsx
or views/xxx.tsx
.
A working example is here: examples/custom-views
ssr.config.js#distDir
The place where react-ssr
outputs production results. (default: .ssr
)
If we use TypeScript or any other library which must be compiled, the config below may be useful:
module.exports = {
// dist folder should be ignored by `.gitignore`
distDir: 'dist/.ssr',
};
ssr.config.js#webpack()
module.exports = {
webpack: (config /* webpack.Configuration */, env /* 'development' | 'production' */) => {
// we can override default webpack config here
return config;
},
};
For example, let's consider we want to import css files directly:
views/index.jsx
import '../styles/index.css';
styles/index.css
body {
background-color: burlywood;
}
Then, we must override the default webpack config like this:
ssr.config.js
module.exports = {
webpack: (config, env) => {
config.module.rules = [
...(config.module.rules),
{
test: /\.css$/i,
use: [
'style-loader',
'css-loader',
],
},
];
return config;
},
};
A working example is here: examples/basic-css-import
Custom Document
Just put _document.jsx
or _document.tsx
into the views root:
./views/_document.jsx
import React from 'react';
import {
Document,
Head,
Main,
} from '@react-ssr/express';
export default class extends Document {
render() {
return (
<html>
<Head>
<title>Default Title</title>
</Head>
<body>
<Main />
</body>
</html>
);
}
};
Note: Please put <Main />
component directly under <body>
tag AND don't wrap <Main />
component with another components because this is a hydration target for the client.
And then, use it as always:
./views/index.jsx
const Index = (props) => {
return <p>Hello Layout!</p>;
};
export default Index;
A working example is here: examples/custom-document
Dynamic Head
We can use the Head
component anyware:
./views/index.jsx
import React from 'react';
import { Head } from '@react-ssr/express';
const Index = (props) => {
return (
<React.Fragment>
<Head>
<title>Dynamic Title</title>
<meta name="description" content="Dynamic Description" />
</Head>
<p>Of course, SSR Ready!</p>
</React.Fragment>
);
};
export default Index;
A working example is here: examples/basic-dynamic-head
Supported UI Framework
- emotion
- styled-components
- material-ui
- antd
- and more...
With Emotion
In order to enable SSR, we must install these packages:
- @emotion/cache as dependencies
- create-emotion-server as dependencies
- babel-plugin-emotion as devDependencies
And then, populate .babelrc
in your project root:
{
"presets": [
"@react-ssr/express/babel"
],
"plugins": [
"emotion"
]
}
A working example is here: examples/with-jsx-emotion
With styled-components
In order to enable SSR, we must install babel-plugin-styled-components
as devDependencies.
And then, populate .babelrc
in your project root:
{
"presets": [
"@react-ssr/express/babel"
],
"plugins": [
"styled-components"
]
}
A working example is here: examples/with-jsx-styled-components
With Material UI
We can use material-ui without extra configuration.
A working example is here: examples/with-jsx-material-ui
With Ant Design
WIP
TypeScript Support
To enable TypeScript engine (.tsx
), just put tsconfig.json
in your project root directory.
The code of TypeScript will be like this:
./package.json
{
"scripts": {
"start": "ts-node server.ts"
}
}
./server.ts
import express, { Request, Response } from 'express';
import register from '@react-ssr/express/register';
const app = express();
(async () => {
// register `.tsx` as a view template engine
await register(app);
app.get('/', (req: Request, res: Response) => {
const message = 'Hello World!';
res.render('index', { message });
});
app.listen(3000, () => {
console.log('> Ready on http://localhost:3000');
});
})();
./views/index.tsx
interface IndexProps {
message: string;
}
export default function Index({ message }: IndexProps) {
return <p>{message}</p>;
}
Packages
package | version |
---|---|
@react-ssr/core | |
@react-ssr/express | |
@react-ssr/nestjs-express |
Examples
- examples/basic-blogging
- examples/basic-css-import
- examples/basic-dynamic-head
- examples/basic-jsx
- examples/basic-nestjs
- examples/basic-nestjs-nodemon
- examples/basic-tsx
- examples/custom-document
- examples/custom-views
- examples/with-jsx-emotion
- examples/with-jsx-material-ui
- examples/with-jsx-styled-components
Starters
Develop examples/<example-folder-name>
$ git clone https://github.com/saltyshiomix/react-ssr.git
$ cd react-ssr
$ yarn
$ yarn dev <example-folder-name>
Articles
The React View Template Engine for Express
[Express] React as a View Template Engine?
Related
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago