0.6.0 • Published 5 years ago

@base-cms/nextjs-web v0.6.0

Weekly downloads
-
License
MIT
Repository
github
Last release
5 years ago

Core NextJS Components for BaseCMS Websites

Install

This package must be used in conjunction with NextJS. In your project root, install this package along with its peer dependencies (this assumes a clean/empty project directory):

yarn add @base-cms/nextjs-web next@7.0.2 apollo-client@^2.4.0 graphql@^14.0.0 graphql-tag@^2.10.0 react@^16.6.0 react-apollo@^2.3.0 react-dom@^16.6.0

Setup

Once the dependencies are installed, a bare minimum Next+BaseCMS setup is required.

Next Config

Create a next.config.js file in the project root and import the BaseCMS next config:

// next.config.js
const withWebsite = require('@base-cms/nextjs-web/next-config');

module.exports = withWebsite({
  distDir: '../.next/build', // Or whatever directory you'd like
  publicRuntimeConfig: {
    // This assumes that you do _not_ want section page paths prefixed with `/section`. Omit this to preserve `/section` prefixing.
    sectionRoutePrefix: '',
  },
  // Any additional/optional config requirements...
});

By default the withWebsite config will add the NODE_ENV value via Webpack's EnvironmentPlugin and add support for importing .graphql files.

Setup Default Routes

Routes are named and support pattern matching. A default set of routes need to be created in order for the site to initially function. By default, these are defined in the site/routes.js file (the site path can be overriden - see Next Server below for details). At bare minimum, a home or index route must be created:

// site/routes.js
module.exports = [
  {
    name: 'home',
    pattern: '/',
    page: 'index',
  },
];

The page property informs Next which page component to load. By default, page components are located in the site/pages directory. A corresponding page must also be created for each route. A contrived example for index would be:

// site/pages/index.jsx
import React from 'react';

const IndexPage = () => (
  <div>
    <h1>Home Page</h1>
  </div>
);

export default IndexPage;

Site Config

A configuration file is used throughout the website to display common elements (such as name, logo, nav items, etc.). By default, the config is defined in the site/config.js file (the site path can be overriden - see Next Server below for details). An baseline config would look similar to this:

// site/config.js
module.exports = {
  name: 'Officer',
  logo: '//cdn.officer.com/files/base/cygnus/ofcr/image/static/logo/site_logo.png',
  primaryNavItems: [
    { to: '/tactical', label: 'Tactical' },
    { to: '/training-careers', label: 'Training & Careers' },
    { to: '/on-the-street', label: 'On the Street' },
    { to: '/investigations', label: 'Investigations' },
    { to: '/command-hq', label: 'Command/HQ' },
    { to: '/directory', label: 'Product Guide' },
    { to: 'https://forum.officer.com', label: 'Forums' },
  ],
  secondaryNavItems: [
    { to: '/features/honoring-the-fallen', label: 'Honoring the Fallen' },
    { to: '/magazine', label: 'Publications' },
    { to: '/subscribe', label: 'Subscribe' },
    { to: '/advertise', label: 'Advertise' },
    { to: '/contact-us', label: 'Contact Us' },
  ],
};

Application Higher-Order Components

The website uses Apollo GraphQL, route definitions, and site configuration globally. To facilitate this, create a site/pages/_app.jsx file with the following setup. This is required for the website to function properly.

// site/pages/_app.jsx
import {
  WebsiteApp,
  withApollo,
  withRouting,
  withSiteConfig,
} from '@base-cms/nextjs-web/app';
// Your route definitions from above... assumes site/routes.js
import routeDefs from '../routes';
// Your site config from above... assumes site/config.js
import config from '../config';

export default withApollo(
  withRouting(routeDefs)(
    withSiteConfig(config)(
      WebsiteApp,
    ),
  ),
);

Next Server

The website utilizes a custom Express server for SSR and proxying to remote BaseCMS services (such as GraphQL, RSS, etc.). To enable this, create a server.js file in the project root and initialize the server:

// server.js
const startServer = require('@base-cms/nextjs-web/server');

// Your website routes. These are required.
const routeDefs = require('./site/routes');
// The port the website should run on
const port = 3005;
// Your external services URL (for GraphQL, RSS, Sitemaps, etc).
// This is required.
const serviceUrl = 'https://[account].4.base-cms.io/[group]';

const boot = async () => {
  // Start the server.
  await startServer({
    port,
    routeDefs,
    serviceUrl,
  });
  console.log(`> Ready on http://0.0.0.0:${port}`);
};

// Boot and immediately throw if there are errors.
boot().catch(e => setImmediate(() => { throw e; }));

If you need to override the default ./site working directory, set the dir option of startServer to a different path, for example ./app or ./my-cool-site.

Running

Once the above steps are completed you can run the website. From the project root, execute NODE_ENV=development node server.js. Once booted, the site will be available on the port specified in the server.js file. You can optionally add a helper script in your package.json file:

{
  "scripts": {
    "dev": "NODE_ENV=development node server.js"
  }
}

Doing so will allow you execute yarn dev.

Development

Anytime changes are made, you must rebuild the dist folder. From the monorepo root, run:

scripts/workspace.sh @base-cms/nextjs-web run build

This will build both CommonJS and ES Module versions of the source using Rollup.