gchessboard

Tutorial

In this tutorial, we will render a chess board component on the page that can be used to play a two-player game of chess, with each side taking turns.

Installing

First, we will install the library and import it into a page. There are two ways to do this.

As an NPM package

npm install gchessboard
import "gchessboard";

Via a <script> tag

<script type="module" src="https://unpkg.com/gchessboard"></script>

Empty chessboard

Once the element is imported, we can render it in a page simply by using the <g-chess-board> tag:

<g-chess-board></g-chess-board>

This renders an chess board with default bundled colors and styles, but with no pieces on it. For a more interesting board, we will have to override some additional attributes.

Adding pieces

We can place pieces onto the board by specifying a position. Like most online chess libraries, gchessboard accepts a Forsyth-Edwards Notation (FEN) string to specify a board position, using the fen attribute.

<g-chess-board
  fen="rnbqkbnr/pppppppp/8/8/8/8/PPPPPPPP/RNBQKBNR">
</g-chess-board>

This renders a board with the standard chess game start position. Because of how common this position is, gchessboard accepts a value of "start" as an alias for the starting position. Thus, the above board could also be produced with the following code:

<g-chess-board fen="start"></g-chess-board>
A FEN string usually has six space-separated components, but only the first (the "placement" attribute) is relevant for determining piece positions. gchessboard will ignore any other components if a full FEN string is passed in. Thus, we could have also passed in a full string of "rnbqkbnr/pppppppp/8/8/8/8/PPPPPPPP/RNBQKBNR w KQkq - 0 1" and the position would have been rendered correctly.

Adding interactivity

The above boards are static and do not allow any pieces to be moved by the user. They are useful if we would like to simply display a chess position on a web page, such as in a blog post describing a game or strategy.

To allow pieces to be moved, we can include the interactive attribute.

<g-chess-board fen="start" interactive></g-chess-board>

This attribute makes the entire board interactive – any piece can be moved around. gchessboard supports three ways to move pieces:

Using the keyboard to move

Keyboard-based moves are a unique feature of gchessboard. The library has been designed to fit the ARIA grid design pattern, which specifies how to handle directional navigation in a two-dimensional container.

Keyboard navigation is enabled when the board has focus. The board is placed in the natural tab order of the page; thus you can navigate to it by using Tab and Shift + Tab. Once the board has focus, you can press Up, Down, Left, and Right to move between squares. Pressing Enter or Space is equivalent to clicking on the square.

You can also use Home and End to move to the start and end of a rank (row), PgUp and PgDown to move to the start and end of a file (column), and Ctrl + Home and Ctrl + End to move to the top-left and bottom-right of the board, respectively.

Adding chess logic

gchessboard is just a board; it has no notion of the rules of chess or how the pieces are allowed to move between squares. To make the component behave more like a chess board, gchessboard provides additional attributes, as well as custom DOM events, that allow you to restrict the set of pieces that can be moved and the squares they can be moved to.

You will usually need to combine the board component with chess logic and state management provided by your own code or an external library. While gchessboard maintains its own representation of the position of the board – especially after a piece is moved – this state should be considered "temporary". Instead, the position of the board should be updated using the fen attribute or the position property after every move. We will make use of events to react to user moves and update state.

For this section of the tutorial, we will use the excellent chess.js library to keep update and keep track of the state of the game.

Restricting which side can move with the turn attribute

We can use the turn attribute to restrict which side is allowed to move.

<g-chess-board fen="start" interactive turn="white"> </g-chess-board>

With this change, only the white pieces can be moved. Internally, this also removes hover and pointer styles from the black pieces, and sets aria-disabled attribute on them so that screen readers do not treat them as clickable.

Update game state with move lifecycle events

Next, we will restrict where a piece is allowed to move to once a move is started, and update the game state after the move has ended. For this, we can leverage three events:

We can use a combination of these three events to create a fully working chess game, with each side taking turns to move!

<g-chess-board
  id="chessful-board" fen="start" interactive turn="white">
</g-chess-board>
import { Chess } from "https://cdn.skypack.dev/chess.js";

const board = document.getElementById("chessful-board");
const game = new Chess();

board.addEventListener("movestart", (e) => {
  console.log(`Move started: ${e.detail.from}, ${e.detail.piece.color} ${e.detail.piece.pieceType}`);
  e.detail.setTargets(
    // This produces a list like ["e3", "e5"]
    game.moves({ square: e.detail.from, verbose: true }).map((m) => m.to)
  );
});

board.addEventListener("moveend", (e) => {
  console.log(`Move ending: ${e.detail.from} -> ${e.detail.to}, ${
    e.detail.piece.color
  } ${e.detail.piece.pieceType}`);
  const move = game.move({
    from: e.detail.from,
    to: e.detail.to
  });
  if (move === null) {
    e.preventDefault();
  }
});

board.addEventListener("movefinished", (e) => {
  board.fen = game.fen();
  board.turn = game.turn() === "w" ? "white" : "black";
});

And that's it! You can edit and run the full example.

More material around style, layout, and animation customization to come soon.