### Install and Start After.js Basic Example (Bash)
Source: https://github.com/jaredpalmer/after.js/blob/master/examples/with-context-api/README.md
Installs the necessary project dependencies using yarn and then starts the development server for the After.js basic example. Requires yarn.
```bash
yarn install
yarn start
```
--------------------------------
### Install Dependencies and Start Project (Bash)
Source: https://github.com/jaredpalmer/after.js/blob/master/examples/with-scss/README.md
Installs the project dependencies using Yarn and then starts the development server for the Razzle/After.js application.
```bash
yarn install
yarn start
```
--------------------------------
### Install Dependencies and Run Material-UI Example (Bash)
Source: https://github.com/jaredpalmer/after.js/blob/master/examples/with-material-ui/README.md
Install the necessary project dependencies using yarn and then start the development server to run the Material-UI example.
```bash
yarn install
yarn start
```
--------------------------------
### Installing and Starting After.js Example (Bash)
Source: https://github.com/jaredpalmer/after.js/blob/master/examples/with-static-export/README.md
Installs project dependencies using Yarn and starts the development server for the After.js static export example.
```bash
yarn install
yarn start
```
--------------------------------
### Install Dependencies and Start Application (Bash)
Source: https://github.com/jaredpalmer/after.js/blob/master/examples/basic/README.md
Installs the project's required dependencies using the Yarn package manager and then starts the development server for the application.
```bash
yarn install
yarn start
```
--------------------------------
### Download and Navigate to Example Directory (Bash)
Source: https://github.com/jaredpalmer/after.js/blob/master/examples/with-scss/README.md
Downloads the basic example project from the After.js GitHub repository using curl and extracts it, then changes the current directory into the extracted example folder.
```bash
curl https://codeload.github.com/jaredpalmer/after.js/tar.gz/master | tar -xz --strip=2 razzle-master/examples/basic
cd basic
```
--------------------------------
### Download and Extract After.js Basic Example (Bash)
Source: https://github.com/jaredpalmer/after.js/blob/master/examples/with-context-api/README.md
Downloads the basic example project from the After.js GitHub repository using curl, extracts it, and navigates into the project directory 'basic'. Requires curl and tar.
```bash
curl https://codeload.github.com/jaredpalmer/after.js/tar.gz/master | tar -xz --strip=2 razzle-master/examples/basic
cd basic
```
--------------------------------
### Install Dependencies and Start (bash)
Source: https://github.com/jaredpalmer/after.js/blob/master/packages/create-after-app/templates/default/README.md
This snippet uses yarn to install the project's dependencies and then starts the application using the defined 'start' script.
```bash
yarn install
yarn start
```
--------------------------------
### Install Dependencies and Run Material UI RTL Example (Bash)
Source: https://github.com/jaredpalmer/after.js/blob/master/examples/with-material-ui-rtl/README.md
These commands install the necessary project dependencies using yarn and then start the development server for the After.js application.
```Bash
yarn install
yarn start
```
--------------------------------
### Creating and Starting After.js App with Example (Bash)
Source: https://github.com/jaredpalmer/after.js/blob/master/examples/with-static-export/README.md
Uses `yarn create after-app` to scaffold a new After.js project based on the `with-static-export` example, navigates into the new directory, and starts the development server.
```bash
yarn create after-app --example with-static-export after-with-static-export
cd after-with-static-export
yarn start
```
--------------------------------
### Install Dependencies and Run After.js Layout Example (Bash)
Source: https://github.com/jaredpalmer/after.js/blob/master/examples/layout-component/README.md
Install the necessary project dependencies using Yarn and then start the development server to run the After.js layout component example.
```bash
yarn install
yarn start
```
--------------------------------
### Create After App with npx (Example)
Source: https://github.com/jaredpalmer/after.js/blob/master/packages/create-after-app/README.md
Initializes a new After.js project named 'my-preact-app' from the 'with-preact' example using npx, navigates into the project directory, and starts the development server.
```Shell
npx create-after-app --example with-preact my-preact-app
cd my-preact-app
npm start
```
--------------------------------
### Download and Navigate to Material-UI Example (Bash)
Source: https://github.com/jaredpalmer/after.js/blob/master/examples/with-material-ui/README.md
Manually download the specific Material-UI example directory from the After.js repository using curl and tar, then change into the downloaded directory.
```bash
curl https://codeload.github.com/jaredpalmer/after.js/tar.gz/master | tar -xz --strip=2 after.js-master/examples/with-material-ui
cd with-material-ui
```
--------------------------------
### Download and Extract Basic Example (Bash)
Source: https://github.com/jaredpalmer/after.js/blob/master/examples/basic/README.md
Downloads the basic example directory from the After.js GitHub repository using curl and tar, then changes the current directory to the extracted example folder.
```bash
curl https://codeload.github.com/jaredpalmer/after.js/tar.gz/master | tar -xz --strip=2 razzle-master/examples/basic
cd basic
```
--------------------------------
### Quickstart with create-after-app (bash)
Source: https://github.com/jaredpalmer/after.js/blob/master/README.md
This snippet shows how to quickly bootstrap a new After.js project using the create-after-app command-line tool. It assumes Razzle is used for tooling.
```bash
yarn global add create-after-app
create-after-app myapp
cd myapp
yarn start
```
--------------------------------
### Bootstrap After.js App with Material-UI Example (Bash)
Source: https://github.com/jaredpalmer/after.js/blob/master/examples/with-material-ui/README.md
Use npx with create-after-app to quickly generate a new After.js project pre-configured with the Material-UI example.
```bash
npx create-after-app --example with-material-ui with-material-ui-app
```
--------------------------------
### Downloading After.js Static Export Example (Bash)
Source: https://github.com/jaredpalmer/after.js/blob/master/examples/with-static-export/README.md
Downloads the `with-static-export` example from the After.js GitHub repository and navigates into the example directory using curl and tar.
```bash
curl https://codeload.github.com/jaredpalmer/after.js/tar.gz/master | tar -xz --strip=2 after.js-master/examples/with-static-export
cd with-static-export
```
--------------------------------
### Quickstart with create-after-app (Bash)
Source: https://github.com/jaredpalmer/after.js/blob/master/packages/after.js/README.md
Use the create-after-app CLI tool to quickly bootstrap a new After.js project integrated with Razzle for isomorphic React application tooling.
```bash
yarn global add create-after-app
create-after-app myapp
cd myapp
yarn start
```
--------------------------------
### Download and Extract Example (bash)
Source: https://github.com/jaredpalmer/after.js/blob/master/packages/create-after-app/templates/default/README.md
This snippet downloads the After.js project archive using curl, extracts the 'basic' example directory using tar, and then navigates into that directory.
```bash
curl https://codeload.github.com/jaredpalmer/after.js/tar.gz/master | tar -xz --strip=2 razzle-master/examples/basic
cd basic
```
--------------------------------
### Bootstrap After.js with Material UI RTL Example using create-after-app (Bash)
Source: https://github.com/jaredpalmer/after.js/blob/master/examples/with-material-ui-rtl/README.md
This command uses `create-after-app` to quickly set up a new After.js project pre-configured with the Material UI RTL example.
```Bash
npx create-after-app --example with-material-ui-rtl with-material-ui-rtl-app
```
--------------------------------
### Create After App with yarn (Example)
Source: https://github.com/jaredpalmer/after.js/blob/master/packages/create-after-app/README.md
Initializes a new After.js project named 'my-preact-app' from the 'with-preact' example using yarn create and navigates into the project directory.
```Shell
yarn create after-app --example with-preact my-preact-app
cd my-preact-app
```
--------------------------------
### Bootstrap After.js Layout Example with create-after-app (Bash)
Source: https://github.com/jaredpalmer/after.js/blob/master/examples/layout-component/README.md
Use the create-after-app command-line tool to quickly generate a new After.js project pre-configured with the layout component example.
```bash
npx create-after-app --example layout-component layout-component-app
```
--------------------------------
### Installing babel-plugin-after
Source: https://github.com/jaredpalmer/after.js/blob/master/packages/babel-plugin-after/README.md
Commands to install the babel-plugin-after package as a development dependency using either npm or Yarn.
```shell
$ npm install babel-plugin-after --save-dev
```
```shell
$ yarn add -D babel-plugin-after
```
--------------------------------
### Download After.js Layout Example Manually (Bash)
Source: https://github.com/jaredpalmer/after.js/blob/master/examples/layout-component/README.md
Download and extract the layout component example directory directly from the After.js GitHub repository using curl and tar, then change into the project directory.
```bash
curl https://codeload.github.com/jaredpalmer/after.js/tar.gz/master | tar -xz --strip=2 after.js-master/examples/layout-component
cd layout-component
```
--------------------------------
### Create After App with npx (Standard)
Source: https://github.com/jaredpalmer/after.js/blob/master/packages/create-after-app/README.md
Initializes a new After.js project named 'my-proj' using npx, navigates into the project directory, and starts the development server.
```Shell
npx create-after-app my-proj
cd my-proj
npm start
```
--------------------------------
### Building After.js App for Production (Bash)
Source: https://github.com/jaredpalmer/after.js/blob/master/examples/with-static-export/README.md
Runs the production build command for the After.js application using Yarn.
```bash
yarn build
```
--------------------------------
### Create After App with yarn (Standard)
Source: https://github.com/jaredpalmer/after.js/blob/master/packages/create-after-app/README.md
Initializes a new After.js project named 'my-proj' using yarn create, navigates into the project directory, and starts the development server.
```Shell
yarn create after-app my-proj
cd my-proj
yarn start
```
--------------------------------
### Using babel-plugin-after via Babel CLI
Source: https://github.com/jaredpalmer/after.js/blob/master/packages/babel-plugin-after/README.md
Command line example showing how to apply the babel-plugin-after plugin when compiling a JavaScript file using the Babel CLI.
```shell
$ babel --plugins after script.js
```
--------------------------------
### Exporting After.js App Statically (Bash)
Source: https://github.com/jaredpalmer/after.js/blob/master/examples/with-static-export/README.md
Runs the static export command for the After.js application using Yarn, generating static HTML files.
```bash
yarn export
```
--------------------------------
### Fetching Data with getInitialProps (JavaScript)
Source: https://github.com/jaredpalmer/after.js/blob/master/README.md
This example demonstrates how to use the static async getInitialProps function in a page component to fetch data. This function runs on both server render and client mounts, making the returned data available via this.props.
```javascript
// ./src/About.js
import React from 'react';
import { NavLink } from 'react-router-dom';
class About extends React.Component {
static async getInitialProps({ req, res, match }) {
const stuff = await CallMyApi();
return { stuff };
}
render() {
return (
HomeAbout
About
{this.props.stuff}
);
}
}
export default About;
```
--------------------------------
### Defining Static Export Logic in After.js (JavaScript)
Source: https://github.com/jaredpalmer/after.js/blob/master/examples/with-static-export/README.md
Defines the `render` and `routes` functions used by Razzle's static export feature. `render` uses `renderStatic` to generate HTML and data, while `routes` specifies the paths to be statically generated.
```js
// ./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'];
};
```
--------------------------------
### Identifying asyncComponent Import Styles
Source: https://github.com/jaredpalmer/after.js/blob/master/packages/babel-plugin-after/README.md
Examples demonstrating various ways asyncComponent can be imported from '@jaredpalmer/after' or '@jaredpalmer/after/asyncComponent', showing how the plugin determines the local variable name.
```javascript
import { asyncComponent } from '@jaredpalmer/after'; // localname is asyncComponent
```
```javascript
import { asyncComponent as foo } from '@jaredpalmer/after'; // localname is foo
```
```javascript
import asyncComponent from '@jaredpalmer/after/asyncComponent'; // localname is asyncComponent
```
```javascript
import foo from '@jaredpalmer/after/asyncComponent'; // localname is foo
```
```javascript
import { asyncComponent as foo, After } from '@jaredpalmer/after'; // localname is foo
```
```javascript
import { After } from '@jaredpalmer/after'; // there is no `asyncComponent` import so babel plugin skips this file
```
```javascript
import loader from '@jaredpalmer/after/asyncComponent'; // localname is loader
import { asyncComponent, After } from '@jaredpalmer/after'; // localname is asyncComponent
```
--------------------------------
### Defining Routes Before Chunk Naming (JSX)
Source: https://github.com/jaredpalmer/after.js/blob/master/UPGRADING.md
This snippet shows the initial structure for defining routes in after.js using `asyncComponent` for code splitting. It demonstrates the basic setup before explicitly specifying webpack chunk names for assets.
```JSX
// 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('./About'),
}),
},
{
path: '/contact-us',
exact: true,
component: asyncComponent({
loader: () => import('./Contact'),
}),
},
];
```
--------------------------------
### Building and Exporting After.js Static Site (Bash)
Source: https://github.com/jaredpalmer/after.js/blob/master/README.md
Provides the command-line instructions using yarn to build the After.js application and then execute the export script to generate the static files based on the configured export functions.
```bash
yarn build
yarn export
```
--------------------------------
### Upgrading Dependencies (v2 to v3) - npm
Source: https://github.com/jaredpalmer/after.js/blob/master/UPGRADING.md
Command to upgrade the @jaredpalmer/after package and react-helmet dependency using npm for the v2 to v3 migration.
```bash
npm install @jaredpalmer/after@latest react-helmet@latest --save
```
--------------------------------
### Building and Exporting Static Site (Bash)
Source: https://github.com/jaredpalmer/after.js/blob/master/packages/after.js/README.md
These bash commands are used to build the After.js application and then execute the static export script. This process generates the static HTML files and associated data files based on the configuration in `./src/static_export.js`.
```Bash
yarn build
yarn export
```
--------------------------------
### Upgrading Dependencies (v1 to v2) - npm
Source: https://github.com/jaredpalmer/after.js/blob/master/UPGRADING.md
Command to upgrade the @jaredpalmer/after package and razzle dependency using npm for the v1 to v2 migration.
```bash
npm install @jaredpalmer/after@latest razzle@latest --save
```
--------------------------------
### Upgrading Dependencies (v2 to v3) - Yarn
Source: https://github.com/jaredpalmer/after.js/blob/master/UPGRADING.md
Command to upgrade the @jaredpalmer/after package and react-helmet dependency using Yarn for the v2 to v3 migration.
```bash
yarn upgrade @jaredpalmer/after react-helmet --latest
```
--------------------------------
### Configuring babel-plugin-after via .babelrc
Source: https://github.com/jaredpalmer/after.js/blob/master/packages/babel-plugin-after/README.md
Shows the recommended way to enable the babel-plugin-after plugin by adding it to the plugins array in a .babelrc configuration file.
```json
{
"plugins": ["after"]
}
```
--------------------------------
### Upgrading Dependencies (v1 to v2) - Yarn
Source: https://github.com/jaredpalmer/after.js/blob/master/UPGRADING.md
Command to upgrade the @jaredpalmer/after package and razzle dependency using Yarn for the v1 to v2 migration.
```bash
yarn upgrade @jaredpalmer/after razzle --latest
```
--------------------------------
### Configuring Babel Plugin After (.babelrc)
Source: https://github.com/jaredpalmer/after.js/blob/master/UPGRADING.md
This snippet shows the content of a `.babelrc` file required to enable the `babel-plugin-after`. It includes the standard `razzle/babel` preset and adds the `after` plugin to the plugins array, automating chunk naming.
```JSON
// .babelrc
{
"presets": [ "razzle/babel" ],
"plugins": [ "after" ]
}
```
--------------------------------
### Setting Transition Behavior in After.js Client
Source: https://github.com/jaredpalmer/after.js/blob/master/packages/after.js/README.md
Explains how to control the page transition behavior by passing the `transitionBehavior` prop to the `` component during client-side hydration. Setting it to "instant" allows the next page to render immediately while `getInitialProps` is pending, providing a faster perceived transition.
```JavaScript
// ./src/client.js
// transitionBehavior = blocked | instant
ensureReady(routes).then(data =>
hydrate(
,
document.getElementById('root')
)
);
```
--------------------------------
### Configuring After.js for Static Export (JS)
Source: https://github.com/jaredpalmer/after.js/blob/master/packages/after.js/README.md
This JavaScript snippet shows the required `render` and `routes` functions to be exported from `./src/static_export.js` for After.js's Static Site Generation (SSG). The `render` function uses `renderStatic` to generate HTML and data, while the `routes` function specifies the paths to be statically generated. It depends on `@jaredpalmer/after` and Razzle manifest files.
```JavaScript
// ./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 = async () => {
return ['/', '/about'];
};
```
--------------------------------
### Configuring Code Splitting in After.js Routes (JavaScript)
Source: https://github.com/jaredpalmer/after.js/blob/master/README.md
Demonstrates how to configure lazy-loaded or code-split routes in After.js using the `asyncComponent` helper. The `loader` function uses dynamic `import()` to load the component asynchronously, and an optional `Placeholder` component can be provided to show content while loading.
```JavaScript
// ./src/_routes.js
import React from 'react';
import Home from './Home';
import { asyncComponent } from '@jaredpalmer/after';
export default [
// normal route
{
path: '/',
exact: true,
component: Home,
},
// codesplit route
{
path: '/about',
exact: true,
component: asyncComponent({
loader: () => import('./About'), // required
Placeholder: () =>
...LOADING...
, // this is optional, just returns null by default
}),
},
];
```
--------------------------------
### Setting Transition Behavior for Page Navigation in After.js Client
Source: https://github.com/jaredpalmer/after.js/blob/master/README.md
This snippet demonstrates how to control the page transition behavior in the client-side client.js file by passing the transitionBehavior prop to the component. Setting it to "instant" allows the next page to render immediately while getInitialProps is pending, providing a more responsive user experience compared to the default "blocked" behavior.
```JavaScript
// ./src/client.js
// transitionBehavior = blocked | instant
ensureReady(routes).then(data =>
hydrate(
,
document.getElementById('root')
)
);
```
--------------------------------
### Implementing Code Splitting in After.js Routes (JavaScript)
Source: https://github.com/jaredpalmer/after.js/blob/master/packages/after.js/README.md
Demonstrates how to configure a route for code splitting using After.js's `asyncComponent` helper. It requires a `loader` function that uses dynamic `import()` and optionally accepts a `Placeholder` component.
```javascript
// ./src/_routes.js
import React from 'react';
import Home from './Home';
import { asyncComponent } from '@jaredpalmer/after';
export default [
// normal route
{
path: '/',
exact: true,
component: Home,
},
// codesplit route
{
path: '/about',
exact: true,
component: asyncComponent({
loader: () => import('./About'), // required
Placeholder: () =>
...LOADING...
, // this is optional, just returns null by default
}),
},
];
```
--------------------------------
### Using babel-plugin-after via Babel Node API
Source: https://github.com/jaredpalmer/after.js/blob/master/packages/babel-plugin-after/README.md
JavaScript code snippet demonstrating how to use the babel-plugin-after plugin programmatically with Babel's Node API.
```javascript
require('babel-core').transform('code', {
plugins: ['after']
});
```
--------------------------------
### Creating a Basic Custom Document Component in After.js
Source: https://github.com/jaredpalmer/after.js/blob/master/README.md
This snippet demonstrates how to create a basic custom Document component in After.js. It uses `getInitialProps` to fetch initial page data and renders the standard HTML structure including After.js components like `AfterRoot`, `AfterData`, `AfterScripts`, and `AfterStyles`, integrating React Helmet for managing head and body attributes.
```JavaScript
// ./src/Document.js
import React from 'react';
import {
AfterRoot,
AfterData,
AfterScripts,
AfterStyles,
} from '@jaredpalmer/after';
class Document extends React.Component {
static async getInitialProps({ renderPage }) {
const page = await renderPage();
return { ...page };
}
render() {
const { helmet } = this.props;
// get attributes from React Helmet
const htmlAttrs = helmet.htmlAttributes.toComponent();
const bodyAttrs = helmet.bodyAttributes.toComponent();
return (
Welcome to the Afterparty
{helmet.title.toComponent()}
{helmet.meta.toComponent()}
{helmet.link.toComponent()}
);
}
}
export default Document;
```
--------------------------------
### Defining Routes in After.js with React Router
Source: https://github.com/jaredpalmer/after.js/blob/master/packages/after.js/README.md
Illustrates how to define application routes using an array of route objects. Each object specifies the `path`, `exact` match requirement, and the React component to render, leveraging React Router's configuration capabilities within After.js.
```JavaScript
// ./src/routes.js
import Home from './Home';
import About from './About';
import Detail from './Detail';
// Internally these will become:
// } />
const routes = [
{
path: '/',
exact: true,
component: Home,
},
{
path: '/about',
component: About,
},
{
path: '/detail/:id',
component: Detail,
},
];
export default routes;
```
--------------------------------
### Handling Redirects with getInitialProps in After.js (JavaScript)
Source: https://github.com/jaredpalmer/after.js/blob/master/packages/after.js/README.md
Explains how to perform server-side redirects by returning `{ redirectTo: "/new-location" }` from `getInitialProps`. This is useful for scenarios like authorization failures.
```javascript
Dashboard.getInitialProps = async ({ match }) => {
try {
const { data } = await fetchProfile();
return { data };
} catch (error) {
if (error.response.status === 401) return { redirectTo: '/login' };
return { error };
}
};
```
--------------------------------
### Handling Dynamic 404 with getInitialProps in After.js (JavaScript)
Source: https://github.com/jaredpalmer/after.js/blob/master/packages/after.js/README.md
Shows the recommended After.js approach for dynamic 404s. The `getInitialProps` function catches an API error and returns `{ statusCode: 404 }`, allowing After.js to automatically render the defined 404 fallback component.
```javascript
function ProductPage({ product }) {
return
{product.name}
;
}
ProductPage.getInitialProps = async ({ match }) => {
try {
const { data } = await fetchProduct(match.params.slug);
return { product: data };
} catch (error) {
if (error.response.status === 404) return { statusCode: 404 };
return { error };
}
};
```
--------------------------------
### Configuring babel-plugin-after with Prefix Option
Source: https://github.com/jaredpalmer/after.js/blob/master/packages/babel-plugin-after/README.md
Demonstrates how to configure the babel-plugin-after plugin in .babelrc to add a custom prefix to generated chunk names.
```json
{
"plugins": ["after", { "prefix": "MyPrefix-" }]
}
```
--------------------------------
### Implementing getInitialProps in a Page Component (JavaScript)
Source: https://github.com/jaredpalmer/after.js/blob/master/packages/after.js/README.md
Demonstrates how to add a static async getInitialProps function to a page component. This function is called on both server render and client mounts, and its returned data is available on this.props.
```javascript
// ./src/About.js
import React from 'react';
import { NavLink } from 'react-router-dom';
class About extends React.Component {
static async getInitialProps({ req, res, match }) {
const stuff = await CallMyApi();
return { stuff };
}
render() {
return (
HomeAbout
About
{this.props.stuff}
);
}
}
export default About;
```
--------------------------------
### Configuring After.js Static Export Functions (JavaScript)
Source: https://github.com/jaredpalmer/after.js/blob/master/README.md
Defines the `render` and `routes` functions required for After.js static site generation. The `render` function uses `renderStatic` to generate HTML and data, while the `routes` function specifies the paths to be statically generated.
```javascript
// ./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 = async () => {
return ['/', '/about'];
};
```
--------------------------------
### Configure After.js Server with Custom Apollo SSR Renderer (JS)
Source: https://github.com/jaredpalmer/after.js/blob/master/packages/after.js/README.md
This snippet sets up an Express server using After.js. It demonstrates how to implement a `customRenderer` function that integrates Apollo Client's server-side rendering flow, fetching data using `getDataFromTree` and extracting the initial state before rendering the React application to an HTML string.
```js
// ./src/server.js
import React from 'react';
import express from 'express';
import { render } from '@jaredpalmer/after';
import { renderToString } from 'react-dom/server';
import { ApolloProvider, getDataFromTree } from 'react-apollo';
import routes from './routes';
import createApolloClient from './createApolloClient';
import Document from './Document';
const chunks = require(process.env.RAZZLE_CHUNKS_MANIFEST);
const server = express();
server
.disable('x-powered-by')
.use(express.static(process.env.RAZZLE_PUBLIC_DIR))
.get('/*', async (req, res) => {
const client = createApolloClient({ ssrMode: true });
const customRenderer = node => {
const App = {node};
return getDataFromTree(App).then(() => {
const initialApolloState = client.extract();
const html = renderToString(App);
return { html, initialApolloState };
});
};
try {
const html = await render({
req,
res,
routes,
chunks,
customRenderer,
document: Document,
});
res.send(html);
} catch (error) {
console.error(error);
res.json({ message: error.message, stack: error.stack });
}
});
export default server;
```
--------------------------------
### Defining Static 404 Route in After.js (JavaScript)
Source: https://github.com/jaredpalmer/after.js/blob/master/packages/after.js/README.md
Shows how to define routes in the `routes.js` file, including a fallback route without a path that React Router and After.js will use for 404s.
```javascript
// ./src/routes.js
import React from 'react';
import Home from './Home';
import Notfound from './Notfound';
import { asyncComponent } from '@jaredpalmer/after';
export default [
// normal route
{
path: '/',
exact: true,
component: Home,
},
// 404 route
{
// there is no need to declare path variable
// react router will pick this component as fallback
component: Notfound,
},
];
```
--------------------------------
### Basic Custom Document Component (After.js, JS)
Source: https://github.com/jaredpalmer/after.js/blob/master/packages/after.js/README.md
Defines a standard custom Document component for After.js applications. It uses `getInitialProps` to retrieve page data and renders the basic HTML structure, incorporating elements from React Helmet and After.js components for styles, data, and scripts. This is useful for basic HTML customization.
```javascript
// ./src/Document.js
import React from 'react';
import {
AfterRoot,
AfterData,
AfterScripts,
AfterStyles,
} from '@jaredpalmer/after';
class Document extends React.Component {
static async getInitialProps({ renderPage }) {
const page = await renderPage();
return { ...page };
}
render() {
const { helmet } = this.props;
// get attributes from React Helmet
const htmlAttrs = helmet.htmlAttributes.toComponent();
const bodyAttrs = helmet.bodyAttributes.toComponent();
return (
Welcome to the Afterparty
{helmet.title.toComponent()}
{helmet.meta.toComponent()}
{helmet.link.toComponent()}
);
}
}
export default Document;
```
--------------------------------
### Handling Dynamic 404 With After.js API (React/JavaScript)
Source: https://github.com/jaredpalmer/after.js/blob/master/README.md
Shows the After.js recommended way to handle dynamic 404s. Instead of conditional rendering in the component, the `getInitialProps` function returns `{ statusCode: 404 }` when a 404 error occurs during data fetching. After.js then automatically renders the configured 404 fallback component.
```JavaScript
function ProductPage({ product }) {
return
{product.name}
;
}
ProductPage.getInitialProps = async ({ match }) => {
try {
const { data } = await fetchProduct(match.params.slug);
return { product: data };
} catch (error) {
if (error.response.status === 404) return { statusCode: 404 };
return { error };
}
};
```
--------------------------------
### Adding babel-plugin-after to Babel Config
Source: https://github.com/jaredpalmer/after.js/blob/master/UPGRADING.md
Configuration for the .babelrc file to include the babel-plugin-after plugin, which is required for the v1 to v2 migration to enable server-side chunk manifest generation.
```js
// .babelrc
{
"presets": [ "razzle/babel" ],
"plugins": [ "after" ]
}
```
--------------------------------
### Configuring 404 Route in After.js Routes (JavaScript)
Source: https://github.com/jaredpalmer/after.js/blob/master/README.md
Defines the route configuration for an After.js application, including a standard home route and a fallback route for 404 errors. The 404 route is identified by the absence of a `path` property and uses the `Notfound` component.
```JavaScript
// ./src/routes.js
import React from 'react';
import Home from './Home';
import Notfound from './Notfound';
import { asyncComponent } from '@jaredpalmer/after';
export default [
// normal route
{
path: '/',
exact: true,
component: Home,
},
// 404 route
{
// there is no need to declare path variable
// react router will pick this component as fallback
component: Notfound,
},
];
```
--------------------------------
### Custom Document with styled-components (After.js, JS)
Source: https://github.com/jaredpalmer/after.js/blob/master/packages/after.js/README.md
Demonstrates how to integrate styled-components with a custom After.js Document component. It utilizes `styled-components`' `ServerStyleSheet` within `getInitialProps` to collect styles during server rendering and injects the resulting style tags into the HTML head, ensuring server-rendered styles are included.
```javascript
// ./src/Document.js
import React from 'react';
import { ServerStyleSheet } from 'styled-components';
import { AfterRoot, AfterData, AfterScripts } from '@jaredpalmer/after';
export default class Document extends React.Component {
static async getInitialProps({ renderPage }) {
const sheet = new ServerStyleSheet();
const page = await renderPage(App => props =>
sheet.collectStyles()
);
const styleTags = sheet.getStyleElement();
return { ...page, styleTags };
}
render() {
const { helmet, styleTags } = this.props;
// get attributes from React Helmet
const htmlAttrs = helmet.htmlAttributes.toComponent();
const bodyAttrs = helmet.bodyAttributes.toComponent();
return (
{helmet.title.toComponent()}
{helmet.meta.toComponent()}
{helmet.link.toComponent()}
{/* here is where we put our Styled Components styleTags... */}
{styleTags}
);
}
}
```
--------------------------------
### Implementing Parameterized Routes and getInitialProps in After.js Component
Source: https://github.com/jaredpalmer/after.js/blob/master/packages/after.js/README.md
Demonstrates a React component (`Detail`) that uses a parameterized route (`/detail/:id`). It shows how to access route parameters (`match.params.id`) within the static `getInitialProps` method to fetch data and how to render nested routes using ``.
```JavaScript
// ./src/Detail.js
import React from 'react';
import { Route } from 'react-router-dom';
class Detail extends React.Component {
// Notice that this will be called for
// /detail/:id
// /detail/:id/more
// /detail/:id/other
static async getInitialProps({ req, res, match }) {
const item = await CallMyApi(`/v1/item${match.params.id}`);
return { item };
}
render() {
return (
Detail
{this.props.item}
{this.props.item.more}
}
/>
{this.props.item.other}
}
/>
);
}
}
export default Detail;
```
--------------------------------
### Handling Dynamic 404 Without After.js API (React/JavaScript)
Source: https://github.com/jaredpalmer/after.js/blob/master/README.md
Demonstrates a manual approach to handling dynamic 404 errors within a component's render logic and `getInitialProps`. It checks for an error with status 404 returned from an API call and conditionally renders the `Notfound` component or a generic error message. This method is less recommended by After.js.
```JavaScript
import Notfound from './Notfound';
function ProductPage({ product, error }) {
if (error) {
if (error.response.status === 404) {
return ;
}
return
Something went Wrong !
;
}
{
/* if there were no errors we have our data */
}
return
{product.name}
;
}
ProductPage.getInitialProps = async ({ match }) => {
try {
const { data } = await fetchProduct(match.params.slug);
return { product: data };
} catch (error) {
return { error };
}
};
```
--------------------------------
### Transforming asyncComponent Import with Variable Path
Source: https://github.com/jaredpalmer/after.js/blob/master/packages/babel-plugin-after/README.md
Illustrates how the plugin handles dynamic imports using template literals with variables, adding a generic webpackChunkName and deriving the chunkName from the variable.
```javascript
const name = "SlimShady"
{
path: "/rap/god",
component: asyncComponent({
loader: () =>
import(
`./pages/${name}`
)
})
}
```
```javascript
const name = "SlimShady"
{
path: "/rap/god",
component: asyncComponent({
loader: () =>
import(
/* webpackChunkName: '[request]' */
`./pages/${name}`
),
chunkName: name
})
}
```
--------------------------------
### Implementing Custom Async Renderer with Apollo and After.js
Source: https://github.com/jaredpalmer/after.js/blob/master/README.md
This snippet shows an Express server configuration using After.js. It defines a custom renderer function that wraps the React application with ApolloProvider, uses getDataFromTree to fetch data asynchronously, renders the component tree to an HTML string, extracts the Apollo cache state, and returns both the HTML and state for server-side rendering.
```javascript
// ./src/server.js
import React from 'react';
import express from 'express';
import { render } from '@jaredpalmer/after';
import { renderToString } from 'react-dom/server';
import { ApolloProvider, getDataFromTree } from 'react-apollo';
import routes from './routes';
import createApolloClient from './createApolloClient';
import Document from './Document';
const chunks = require(process.env.RAZZLE_CHUNKS_MANIFEST);
const server = express();
server
.disable('x-powered-by')
.use(express.static(process.env.RAZZLE_PUBLIC_DIR))
.get('/*', async (req, res) => {
const client = createApolloClient({ ssrMode: true });
const customRenderer = node => {
const App = {node};
return getDataFromTree(App).then(() => {
const initialApolloState = client.extract();
const html = renderToString(App);
return { html, initialApolloState };
});
};
try {
const html = await render({
req,
res,
routes,
chunks,
customRenderer,
document: Document,
});
res.send(html);
} catch (error) {
console.error(error);
res.json({ message: error.message, stack: error.stack });
}
});
export default server;
```
--------------------------------
### Initial After.js Custom Document Component (Old) - JSX
Source: https://github.com/jaredpalmer/after.js/blob/master/UPGRADING.md
This is the original implementation of a custom `Document.js` component in After.js. It manually includes client-side CSS and JavaScript assets by accessing them from the `assets` prop passed to `getInitialProps` and rendering `` and `