Coder Social home page Coder Social logo

isomorph's Introduction

Isomporh

A simple framework inspired by Next.js to create Server and Statically Rendered React Apps.

Read the blog post detailing the process of ideation and creation of this project.

Work In Progress

  • Supporting dynamic page routes.

Existing Features

  • Server Side Rendering with data fetching on the server.
  • Static Page Generation and serving with revalidation and Stale-While-Revalidate approach of handling serving.
  • Server Side data fetching utilities like getDataOnServer and getStaticProps and function to populate page meta data with getPageMeta.
  • Full Client-Side Rendering/Hydration of pages to enable user interactivity and events.
  • useInitialData hook to access initial data fetched on the server across the entire component chain.
  • All Environment variables accessible on server-side and variables starting ISOMORPH_PUBLIC_... accessible on the client-side.
  • Minification and Tree-Shaking of code in Production mode.
  • Bundle Caching in Production mode to enable super-fast load times for both server-rendered and statically generated pages post first build.
  • Custom error pages using _error for handling 404s and 500s.

Installation and Setup

Using create-isomorph-app

The simplest way to get started with an isomorph project is using create-isomorph-app.

npm i -g isomorph-web
npx create-isomorph-app [project directory] [?project name]

// ex:
npx create-isomorph-app my-isomorph-project "Isomorph App"

Setting Up Manually

As of now to setup an isomorph project, create a directory for your project. I'm assuming you have npm and Node.js already installed.

mkdir my-isomorph-project
cd ./my-isomorph-project
npm init -y

Once done with this, install isomorph-web using npm or yarn.

yarn add isomorph-web

// or

npm i --save isomorph-web

Create an src folder, this will house all your components, utils and project related JavaScript code. Inside it create a pages folder that will house your page files and have React components associated with them.

Check the Required Project Structure section to know the sample structure of isomorph projects.

Update your package.json file's scripts to the following:

"scripts": {
+ 	"build": "isomorph-web build",
+ 	"dev": "isomorph-web dev",
+ 	"start": "isomorph-web start"
}

Once done, run the dev server using:

npm run dev

Required Project Structure

Your pages have to be housed inside the src/pages folder of your project directory.

.
โ”œโ”€โ”€ src/
โ”‚   โ”œโ”€โ”€ pages/
โ”‚   โ”‚   โ”œโ”€โ”€ index.js
โ”‚   โ”‚   โ””โ”€โ”€ static-page.js
โ”‚   โ”œโ”€โ”€ components/
โ”‚   โ”‚   โ””โ”€โ”€ ...
โ”‚   โ””โ”€โ”€ utils/
โ”‚       โ””โ”€โ”€ ...
โ””โ”€โ”€ package.json

I'm currently working on adding dynamic route support soon.

Pages Structure and Data Fetching

Pages are simple React component files that expose a default React component export, along with a few other exports to facilitate data fetching and meta data handling.

// No need to 'import React from "react";', it's always in scope.
import useInitialData from "isomorph-web/package/hooks/useInitialData";

const PageComponent = () => {
	const initialData = useInitialData(); // Use this hook to access data fetched for the page in getPropsOnServer/getStaticProps.

	return (
		<>
			Data received from server: {initialData.variable}. I can even have
			environment variables: {process.env.ISOMORPH_PUBLIC_ENV_VAR}.
		</>
	);
};

export default PageComponent;

// For server-rendered pages, for static pages, use getStaticProps or skip both of these data fetcher functions.
export const getPropsOnServer = async (context) => {
	console.log(
        context.req,
		context.res,
        context.cookies, // Parsed cookie object for you
        context.env, // Environment variables, would not be exposed to the client.
        context.url // Request url path.
        context.query   // Request query parameters
    );

    const variable = await getVariableFromDatabase(context.url, context.cookies);
    return { variable }; // This will be passed to the page component and can be accessed using the `useInitialData` hook.
};

// For static pages
export const getStaticProps = async (context) => {
    console.log(
        context.env, // Environment variables, would not be exposed to the client.
        context.url // Request url path.
    );
    return { revalidate: 3 * 60, variable: 5 }; // Revalidate the page after 3 minutes, pass the rest of the payload as initial data.
};

Handling Page Meta Data

What's server-side and static rendering without SEO benefits. For that purpose, we have the getPageMeta function that will allow you to add all meta tags, link tags, script tags you need.

// In your page file.

// src/pages/index.js

...

export const getPageMeta = () => {
	return {
		title: "Home Page",
		meta: [
			{
				name: "description",
				content: "A simple page generated on the server-side.",
			},
			{
				name: "viewport",
				content: "width=device-width, initial-scale=1.0",
			},
		],
		links: [
			{
				rel: "stylesheet",
				href: "https://cdn.jsdelivr.net/npm/[email protected]/dist/css/bootstrap.min.css",
			},
		],
		scripts: [
			{
				type: "application/ld+json",
				content: '{ type: "Your JSON LD data for rich results" }',
			},
		],
	};
};

Determining When your page is on the client-side

Components rendered on the client-side are hydration-error free, that's because they are not hydrated in the first place, they are re-rendered, which means as long as your pages are not super heavy and big, you can avoid worrying about errors like HTML on server did not match the HTML on client which can be frustrating and error-prone when writing React apps that render and function on both the client and the server-side without any impact on page load and performance.

To find out whether your app is on the client-side, just use the following:

typeof window === "undefined"; // If this is true, you're on the server-side.

Environment Variables

Environment variables are fully supported, use a .env file at the root of your folder to expose environment variables for your app. On the server-side and while rendering your page components on the server-side, you have access to all environment variables.

On the client-side, all environment variables starting with ISOMORPH_PUBLIC_ are automatically exposed.

Custom Error Pages

For handling custom UIs for 404 and 500 errors, you can create a pages/_error.js file.

const ErrorComponent = ({ statusCode, error }) => {
	// statusCode -> 404 | 500
	// error -> The error message that was received from the server.
	return (
		<>
			<h4>{statusCode}</h4>
			<br />
			{error}
		</>
	);
};

export default ErrorComponent;

Building and Serving on Production

Use the following command to compile your source code to production config.

npm run build

Use the following to start the server.

npm run start

This project is still a WIP and will be for the near future, check the Work In Progress section to see what's still pending.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.