after.js

repository·master·Indexed 26 days ago

https://github.com/jaredpalmer/after.js

A framework that brings Next.js-like data fetching capabilities (getInitialProps) to any React SSR application using React Router. It provides route-based code-splitting and seamless data loading. Key features include support for Static Site Generation (SSG) via renderStatic, imperative data prefetching and refetching, and integration with tools like Razzle, Redux, and Material-ui.

Tokens
14K
Snippets
47
Records
79
Agent score
87%

What's inside after.js

  1. Quickstart After.js with create-after-app

    master

    You can quickly bootstrap an SSR React application with After.js using the create-after-app CLI tool. This setup assumes you have the tooling for an isomorphic React application (like Razzle) configured.

    Run the following commands to create and start your project:

    yarn global add create-after-app
    create-after-app myapp
    cd myapp
    yarn start
  2. Run the Razzle x After.js with Context API example

    master

    To run this specific example, you can download the example directory from the repository and run it using yarn.

    Note: The provided download command in the source points to razzle-master/examples/basic, but for this specific context API example, you should ensure you are in the correct directory within the repository structure.

  3. Configure asyncComponent routes manually (without Babel plugin)

    master

    If you are NOT using babel-plugin-after, you must manually configure asyncComponent in your routes.js file to ensure assets are sent correctly. This requires two things:

    1. Adding a /* webpackChunkName: "name" */ magic comment inside the import() statement.
    2. Providing a chunkName property in the asyncComponent configuration that matches the magic comment exactly.

    Important: If the same component is used across different routes, the webpackChunkName and chunkName must be identical in all instances.

    // routes.js
    
    import Home from './Home';
    import { asyncComponent } from '@jaredpalmer/after';
    
    export default [
      {
        path: '/',
        exact: true,
        component: Home,
      },
      {
        path: '/about',
        exact: true,
        component: asyncComponent({
          loader: () => import(/* webpackChunkName: "whatever" */ './About'),
          chunkName: 'whatever',
        }),
      },
      {
        path: '/contact-us',
        exact: true,
        component: asyncComponent({
          loader: () => import(/* webpackChunkName: "ContactUs" */ './Contact'),
          chunkName: 'ContactUs',
        }),
      },
    ];
  4. Implement Static Site Generation (SSG) with After.js

    master

    To build static webapps using After.js and Razzle, you must implement two exported functions in a static_export.js file:

    1. render: An async function that returns the HTML and data. It uses the renderStatic function from @jaredpalmer/after to handle data loading from static files instead of calling getInitialProps after the export is complete.
    2. routes: An async function that returns an array of all page paths you want to statically generate.

    Build and Export Commands:

    • Build the app: yarn build
    • Run the static export: yarn export
    • The output is located in the build/public directory.
    // ./src/static_export.js
    
    import { renderStatic } from '@jaredpalmer/after';
    import appRoutes from './routes';
    
    const assets = require(process.env.RAZZLE_ASSETS_MANIFEST);
    const chunks = require(process.env.RAZZLE_CHUNKS_MANIFEST);
    
    export const render = async (req, res) => {
      const { html, data } = await renderStatic({
        req,
        res,
        routes: appRoutes,
        assets,
        chunks,
      });
      res.json({ html, data });
    };
    
    export const routes = () => {
      return ['/', '/about'];
    };
  5. Bootstrap the Material-ui x After.js RTL example using `create-after-app`

    master

    You can use the create-after-app CLI tool to bootstrap a new project based on the Material-ui with RTL (Right-to-Left) direction example. This is the recommended way to start a new application using this specific configuration.

    npx create-after-app --example with-material-ui-rtl with-material-ui-rtl-app
  6. Run the Razzle x After.js SCSS example

    master

    To explore a basic implementation of After.js with Razzle and SCSS, you can download the specific example directory and run it locally using yarn.

    Note: The provided download command in the source points to razzle-master/examples/basic. Ensure you are targeting the correct example directory for SCSS if you are following this specific guide.

  7. Initialize an After.js app from an example

    master

    To start a project using a specific configuration from the available examples, use the --example flag followed by the example name.

    # Using npx with an example
    npx create-after-app --example with-preact my-preact-app
    cd my-preact-app
    npm start
    
    # Using yarn with an example
    yarn create after-app --example with-preact my-preact-app
    cd my-preact-app
  8. Configure a 404 fallback page

    master

    You can define a custom 404 fallback component in your routes.js file by adding a route without a path property. To ensure the server sends the correct HTTP status code, the component must set staticContext.statusCode to 404 within a Route render prop.

    // ./src/routes.js
    import React from 'react';
    import Home from './Home';
    import Notfound from './Notfound';
    
    export default [
      { path: '/', exact: true, component: Home },
      { component: Notfound }, // 404 route
    ];
    
    // ./src/Notfound.js
    import React from 'react';
    import { Route } from 'react-router-dom';
    
    function NotFound() {
      return (
        <Route
          render={({ staticContext }) => {
            if (staticContext) staticContext.statusCode = 404;
            return <div>The Page You Were Looking For Was Not Found</div>;
          }}
        />
      );
    }
    
    export default NotFound;
  9. Migrate from v2 to v3: Update server.js

    master

    When upgrading to v3, you must import the chunks.json file generated by Razzle and pass it as the chunks parameter to the render method in your server.js file.

    1. Import the manifest: const chunks = require(process.env.RAZZLE_CHUNKS_MANIFEST);
    2. Pass it to render: Add chunks to the object passed to the render function.
    // server.js
    
    import express from 'express';
    import { render } from '@jaredpalmer/after';
    import routes from './routes';
    import MyDocument from './Document';
    
    const assets = require(process.env.RAZZLE_ASSETS_MANIFEST);
    const chunks = require(process.env.RAZZLE_CHUNKS_MANIFEST); // 👈 import chunks.json
    
    const server = express();
    server
      .disable('x-powered-by')
      .use(express.static(process.env.RAZZLE_PUBLIC_DIR))
      .get('/*', async (req, res) => {
        try {
          // Pass document in here.
          const html = await render({
            req,
            res,
            document: MyDocument,
            chunks, // 👈 pass it to render method
            routes,
            assets,
          });
          res.send(html);
        } catch (error) {
          console.log(error);
          res.json(error);
        }
      });
    
    export default server;
  10. Migrate from After.js v1 to v2

    master
    Upgrading from v1 to v2 improves asset loading performance. In v2, After.js sends all JS and CSS files required for the current request in the initial server response, preventing the 'flash of unstyled content' and the slow chunk-fetching process required by the ensureReady method in v1.
  11. Implement Context API with After.js and Razzle

    master

    This example demonstrates how to integrate React's Context API with After.js and Razzle. To implement this pattern, you should examine how the context is initialized and rendered on the server versus the client.

    Key files to inspect for this pattern:

    • Document.js: To see how the context is rendered on the server side.
    • client.js: To see how the context is hydrated or initialized on the client side.