Giter Site home page Giter Site logo

nextjs-graphql-sample's Introduction

Next.js project example with TypeScript & GraphQl

Description

This is an example/boilerplate of a nextjs project using Typescript and Apollo.

The main idea behind the example is to show the best typescript and GraphQL usage by integration of the Apollo client and types generating using GraphQL Code Generator.

Moreover, for writing styles it suggests no less interesting approach with combining styled-components and styled-system Read more. ๐Ÿ˜ƒ

In this example, Apollo is integrated by wrapping our pages with HOC. Using the HOC pattern we're able to pass down a central store of query result data created by Apollo into our React component hierarchy defined inside each page of our Next application.

Table of Contents

Usage

Install it and run:

npm install
npm run dev

# or

yarn
yarn dev

File structure

    .
    โ”œโ”€โ”€ ...
    โ”œโ”€โ”€ generated/             # generated graphql types
    โ”œโ”€โ”€ graphql/               # graphql queries and mutations splitted by entities
    โ”œโ”€โ”€ interfaces/            # custom ts interfaces
    โ”œโ”€โ”€ utils/                 # app utilities
    โ”œโ”€โ”€ pages/                 # next.js pages
    โ”œโ”€โ”€ server/                # custom server
    โ”œโ”€โ”€ views
    โ”‚   โ”œโ”€โ”€ components/        # components
    โ”‚   โ”œโ”€โ”€ layouts/           # application layouts
    โ”‚   โ”œโ”€โ”€ styled/            # styled components + styled system types
    โ”‚   โ””โ”€โ”€ ui/                # ui components(Button, Inputs, etc.)
    โ””โ”€โ”€ ...

Configuration

Also, this example is easily configurable. The main config file next.config.js is placed in the root. You can engage all the needed plugins there. Next-compose-plugins is used for composing all the plugins together, It provides a cleaner API for enabling and configuring plugins.

const withPlugins = require("next-compose-plugins");
const withTypescript = require("@zeit/next-typescript");
const withLess = require("@zeit/next-less");

module.exports = withPlugins(
  [
    // add a plugin without a configuration
    withTypescript,

    // add a plugin with specific configuration
    [
      withLess,
      {
        lessLoaderOptions: {
          javascriptEnabled: true
        }
      }
    ]
  ],
  nextConfig // next.js configuration
);

Making GraphQl queries and mutations

In order to make a GraphQL query or request, firstly we should describe the schemas, all of them should be placed in the graphql folder, we actually splitted them by entities for convenience of use.

Then we must generate typescript types read more. After this, you could use these generated components:

<LoginComponent>
{(<LoginMutation>, <LoginVariables>) => (
  ...code
)}
</LoginComponent>

Styling

This exapmle uses styled-components along with styled-system approach.

Styled-components is a CSS-in-JS library which allows you to write actual CSS code to style your components.

Styled-System provides you with a set of utilities that map props to your design system. It uses the concept of style functions. Each style function exposes its own set of props that style elements based on values defined in your design system theme. It has a rich API with functions for most CSS properties.

The Design Styled System theme object is intended to be a general purpose format for storing design system style values and scales:

const theme = {
  breakpoints: [32, 48, 64],
  space: [0, 4, 8, 16, 32, 64, 128, 256, 512],
  fontSizes: [12, 14, 16, 20, 24, 36, 48, 80, 96],
  fontWeights: [100, 200, 300, 400, 500, 600, 700, 800, 900],
  colors: {
    primary: "#000",
    secondary: "#ccc",
    ...
  },
   buttonSizes: {
    xs: `
      height: 16px;
      padding: 0 16px;
      font-size: 10px;
    `,
    sm: `
      height: 24px;
      padding: 0 24px;
      font-size: 13px;
    `,
    md: `
      height: 34px;
      padding: 0 34px;
      font-size: 14px;
      letter-spacing: 0.4px;
    `
  ...

Our styled components utilize what we call system props to apply a custom set of props to a component. We adopted this approach by creating seperate types like layout, typography, flexbox, and others. This means that every component is guaranteed to have the same API.

Here is an example of the common type, we use the compose utility to create custom type that each new component can use.

import * as SS from "styled-system";

// typescript type
export type CommonProps = SS.SpaceProps &
  SS.WidthProps &
  SS.HeightProps &
  SS.ColorProps &
  SS.FontSizeProps;

// common type
export default SS.compose(
  SS.space,
  SS.width,
  SS.height,
  SS.color,
  SS.fontSize
);

This is a component for styling headings, here we import our custom common and typography functions, moreover, we could extend it with our custom css styles. Also, we add some default styled-system props.

import styled, { StyledComponent } from "styled-components";
import { borders, BordersProps } from "styled-system";

import common, { CommonProps } from "./types/common";
import typography, { TypographyProps } from "./types/typography";

type Props = CommonProps & TypographyProps & BordersProps;

const Heading: StyledComponent<Props> = styled("h1")(
  { margin: "0 0 20px" },

  common,
  borders,
  typography
);

Heading.defaultProps = {
  fontSize: [2, 3, 4],
  fontWeight: 5,
  color: "primary"
};

Heading.displayName = "Heading";

export default Heading;

Eventually, we can easily reuse this styled component adding different props.

// (theme.fontSizes[4])
<Heading fontSize={4} />

// (theme.space[3])
<Heading m={2} />

// (theme.colors.blacks[0])
<Heading color="blacks.3" />

Features

GraphQL types

To generate GraphQL types out of GraphQL schemas we use GraphQL Code Generator, it takes all our GraphQL queries and mutations from graphql/**/* and generates typescript components into a generated/apolloComponents.tsx file, so after you could use it inside your components. In order to generate it run npm run generate or yarn generate command. You should regenerate types every time any graphql mutation or query changes โ—

Protected routes

For catching authentication errors we use HOC, it makes an initial GraphQL query to get the authenticated. If there is no authenticated user it redirects to the login page.

export const withAuth = <T extends object>(
  C: React.ComponentClass<T> | React.FC
) => {
  return class AuthComponent extends React.Component<T> {
    static async getInitialProps({
      apolloClient,
      ...ctx
    }: NextContextWithApollo) {
      const response = await apolloClient.query<MeQuery>({ query: meQuery });
      if (!response || !response.data || !response.data.me) {
        redirect(ctx, "/login");

        return {
          me: null
        };
      }

      return {
        me: response.data.me
      };
    }

    render() {
      return <C {...this.props} />;
    }
  };
};

License

nextjs-graphql-sample is Copyright ยฉ 2015-2019 Codica. It is released under the MIT License.

About Codica

Codica logo

We love open source software! See our other projects or hire us to design, develop, and grow your product.

nextjs-graphql-sample's People

Contributors

yuriykorovko avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar

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.