{"id":50,"date":"2025-01-02T21:48:00","date_gmt":"2025-01-02T21:48:00","guid":{"rendered":"https:\/\/blog.chessboardmagic.com\/?p=50"},"modified":"2025-09-28T21:50:51","modified_gmt":"2025-09-28T21:50:51","slug":"chess-web-programming-part-eight-chess-com-api","status":"publish","type":"post","link":"https:\/\/blog.chessboardmagic.com\/index.php\/2025\/01\/02\/chess-web-programming-part-eight-chess-com-api\/","title":{"rendered":"Chess Web Programming: Part Eight: Chess.com API"},"content":{"rendered":"\n<p><strong>Working with the Chess.com API<\/strong><\/p>\n\n\n\n<p>My journey into programming chess applications started with&nbsp;<strong><a href=\"https:\/\/chessboardmagic.com\/\">Chessboard Magic<\/a><\/strong>, a personal project that turned into a platform with over 34 unique chess-based applications. This blog continues my&nbsp;<strong>Chess Web Programming<\/strong>&nbsp;series, diving into one of the most exciting aspects of modern development: working with APIs. In this installment, we\u2019ll explore the&nbsp;<strong>Chess.com API<\/strong>, learn how to interact with it, and create a React application to fetch and display games from any Chess.com user in a structured and beginner-friendly way.<\/p>\n\n\n\n<h4 class=\"wp-block-heading\"><a href=\"https:\/\/lichess.org\/@\/HollowLeaf\/blog\/chess-web-programming-part-eight-chesscom-api\/mGHcVFEJ#recap-of-the-previous-parts\"><\/a>Recap of the Previous Parts<\/h4>\n\n\n\n<p>Before we dive into the Chess.com API, here&#8217;s a quick recap of the earlier blogs in the series:<\/p>\n\n\n\n<ol class=\"wp-block-list\">\n<li><strong><a href=\"https:\/\/lichess.org\/@\/HollowLeaf\/blog\/chess-web-programming-part-one-getting-started\/8ZKpwJU8\">Getting Started<\/a><\/strong>: Using\u00a0<code>react-chessboard<\/code>\u00a0and\u00a0<code>chess.js<\/code>\u00a0to set up a functional chessboard.<\/li>\n\n\n\n<li><strong><a href=\"https:\/\/lichess.org\/@\/HollowLeaf\/blog\/chess-web-programming-part-two-stockfish\/PdeOTODf\">Integrating Stockfish<\/a><\/strong>: Enhancing the application by suggesting the best move using Stockfish.<\/li>\n\n\n\n<li><strong><a href=\"https:\/\/lichess.org\/@\/HollowLeaf\/blog\/chess-web-programming-part-three-deploying-your-application\/J3GdsKZP\">Deploying Your Application<\/a><\/strong>: A guide to hosting your chess application online.<\/li>\n\n\n\n<li><strong><a href=\"https:\/\/lichess.org\/@\/HollowLeaf\/blog\/chess-web-programming-part-four-chessboard-customisation\/Is0jxElj\">Customizing the Chessboard<\/a><\/strong>: Styling and implementing features like custom piece sets and square highlighting.<\/li>\n\n\n\n<li><strong><a href=\"https:\/\/lichess.org\/@\/HollowLeaf\/blog\/chess-web-programming-part-five-game-review\/32JsEsrs\">Game Review<\/a><\/strong>: Adding features like move highlighting and navigation for game analysis.<\/li>\n\n\n\n<li><strong><a href=\"https:\/\/lichess.org\/@\/HollowLeaf\/blog\/chess-web-programming-part-six-essential-resources\/Yg5HxCt6\">Essential Resources<\/a><\/strong>: Tools, libraries, and learning materials to support chess application development.<\/li>\n\n\n\n<li><strong><a href=\"https:\/\/lichess.org\/@\/HollowLeaf\/blog\/chess-web-programming-part-seven-lichess-api\/6MgfKoeh\">Lichess API<\/a><\/strong>: Learning how to use the Lichess.org API.<\/li>\n<\/ol>\n\n\n\n<blockquote class=\"wp-block-quote is-layout-flow wp-block-quote-is-layout-flow\">\n<p><strong>Note:<\/strong>&nbsp;This blog assumes that you\u2019ve followed the previous parts of the series, particularly&nbsp;<strong>Blog 1<\/strong>, which covers setting up the foundational tools and concepts. You should already have the necessary software installed (e.g., Node.js, Visual Studio Code) and a basic understanding of React web programming. If you haven\u2019t reviewed Blog 1 yet, we recommend starting there to ensure you\u2019re set up for success.<\/p>\n<\/blockquote>\n\n\n\n<h2 class=\"wp-block-heading\"><a href=\"https:\/\/lichess.org\/@\/HollowLeaf\/blog\/chess-web-programming-part-eight-chesscom-api\/mGHcVFEJ#what-are-apis\"><\/a>What Are APIs?<\/h2>\n\n\n\n<p>APIs (Application Programming Interfaces) act as intermediaries that allow software applications to communicate with one another. They provide a set of rules and protocols for accessing a service or application&#8217;s features or data. For example, when you check the weather on your phone, the app fetches the data from a server using APIs. Similarly, we\u2019ll use the Chess.com API to retrieve chess game data.<\/p>\n\n\n\n<h4 class=\"wp-block-heading\"><a href=\"https:\/\/lichess.org\/@\/HollowLeaf\/blog\/chess-web-programming-part-eight-chesscom-api\/mGHcVFEJ#what-is-a-restful-api\"><\/a><strong>What Is a RESTful API?<\/strong><\/h4>\n\n\n\n<p>A RESTful API (Representational State Transfer API) is a type of API that adheres to specific architectural principles. It uses standard HTTP methods such as&nbsp;<code>GET<\/code>,&nbsp;<code>POST<\/code>,&nbsp;<code>PUT<\/code>, and&nbsp;<code>DELETE<\/code>&nbsp;to manage resources (like game data or user profiles).<br>RESTful APIs:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Are stateless, meaning every request from the client to the server must contain all the information needed to process the request.<\/li>\n\n\n\n<li>Use endpoints (specific URLs) to access different resources.<\/li>\n<\/ul>\n\n\n\n<p>For instance, the chess.com API uses endpoints to provide access to specific types of data. Here&#8217;s an example:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li><strong>Endpoint<\/strong>:\u00a0<code>https:\/\/api.chess.com\/pub\/player\/{username}\/games\/{year}\/{month}<\/code><\/li>\n\n\n\n<li><strong>Purpose<\/strong>: Fetches games played by a given Chess.com user.<\/li>\n<\/ul>\n\n\n\n<p>In this blog, we\u2019ll focus on the&nbsp;<strong>Games<\/strong>&nbsp;endpoint to fetch and display a user\u2019s game history.<\/p>\n\n\n\n<blockquote class=\"wp-block-quote is-layout-flow wp-block-quote-is-layout-flow\">\n<p><strong>What Is HTTP?<\/strong><br>HTTP (HyperText Transfer Protocol) is the foundation of communication on the web. It defines how messages are formatted and transmitted between clients (like a browser or application) and servers. For example, when your application sends a request to the Chess.com API, it uses HTTP to communicate. Common HTTP methods include:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li><strong>GET<\/strong>: Retrieve data from a server.<\/li>\n\n\n\n<li><strong>POST<\/strong>: Send data to a server.<\/li>\n\n\n\n<li><strong>PUT<\/strong>: Update data on a server.<\/li>\n\n\n\n<li><strong>DELETE<\/strong>: Remove data from a server.<\/li>\n<\/ul>\n<\/blockquote>\n\n\n\n<h4 class=\"wp-block-heading\"><a href=\"https:\/\/lichess.org\/@\/HollowLeaf\/blog\/chess-web-programming-part-eight-chesscom-api\/mGHcVFEJ#the-chesscom-api\"><\/a>The Chess.com API<\/h4>\n\n\n\n<p>The&nbsp;<strong><a href=\"https:\/\/www.chess.com\/news\/view\/published-data-api\">Chess.com API<\/a><\/strong>&nbsp;is a RESTful API that provides developers access to various chess-related data. It allows you to retrieve information about players, games, tournaments, and more.<br>Here are some of its key features:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li><strong>User Profiles<\/strong>: Fetch details about a specific Chess.com user, including ratings, titles, and membership status.<\/li>\n\n\n\n<li><strong>Game Archives<\/strong>: Access a player\u2019s monthly game archives, which include all games played during a specific month.<\/li>\n\n\n\n<li><strong>Clubs and Tournaments<\/strong>: Retrieve details about clubs, tournaments, and events.<\/li>\n<\/ul>\n\n\n\n<p>For this tutorial, we\u2019ll use the&nbsp;<strong>Game Archives<\/strong>&nbsp;endpoint to:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Fetch a user&#8217;s game history for a specific month.<\/li>\n\n\n\n<li>Include details like the result, time controls, and opening name.<\/li>\n<\/ul>\n\n\n\n<h4 class=\"wp-block-heading\"><a href=\"https:\/\/lichess.org\/@\/HollowLeaf\/blog\/chess-web-programming-part-eight-chesscom-api\/mGHcVFEJ#example-endpoint-game-archives\"><\/a>Example Endpoint: Game Archives<\/h4>\n\n\n\n<p>To fetch the game archive for a Chess.com user:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>https:&#47;&#47;api.chess.com\/pub\/player\/{username}\/games\/{year}\/{month}<\/code><\/pre>\n\n\n\n<p>For example:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>https:&#47;&#47;api.chess.com\/pub\/player\/hollowleaf\/games\/2024\/11<\/code><\/pre>\n\n\n\n<p>By understanding how endpoints work, you\u2019ll be able to explore other parts of the Chess.com API and integrate additional features into your application in the future.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\"><a href=\"https:\/\/lichess.org\/@\/HollowLeaf\/blog\/chess-web-programming-part-eight-chesscom-api\/mGHcVFEJ#setting-up-a-react-application\"><\/a>Setting Up a React Application<\/h2>\n\n\n\n<p>In this section, we\u2019ll create a React application from scratch using&nbsp;<code>Create React App<\/code>. This will serve as the foundation for our Chess.com API integration.<\/p>\n\n\n\n<h4 class=\"wp-block-heading\"><a href=\"https:\/\/lichess.org\/@\/HollowLeaf\/blog\/chess-web-programming-part-eight-chesscom-api\/mGHcVFEJ#step-1-create-a-new-react-application\"><\/a>Step 1: Create a New React Application<\/h4>\n\n\n\n<p>React is a popular JavaScript library for building user interfaces. To get started, we\u2019ll use a tool called&nbsp;<strong>Create React App<\/strong>, which sets up a new project with all the necessary configurations and dependencies pre-installed.<\/p>\n\n\n\n<ol class=\"wp-block-list\">\n<li><strong>Open Your Terminal<\/strong><br>You\u2019ll need a terminal or command-line tool to run commands. On Windows, you can use Command Prompt or PowerShell. On macOS or Linux, use the built-in terminal.<\/li>\n\n\n\n<li><strong>Run the Create React App Command<\/strong><br>In your terminal, type\u00a0<code>npx create-react-app chessdotcom-api-app<\/code>. The\u00a0<code>npx<\/code>\u00a0command ensures that you\u2019re using the latest version of Create React App, while\u00a0<code>chessdotcom-api-app<\/code>\u00a0is the name of your project folder. This command downloads and installs all the dependencies required for a React project. It might take a few minutes depending on your internet connection.<\/li>\n\n\n\n<li><strong>Navigate Into Your Project Folder<\/strong><br>Once the installation is complete, use the\u00a0<code>cd chessdotcom-api-app<\/code>\u00a0command to navigate into the folder where your new React project is located.<\/li>\n\n\n\n<li><strong>What\u2019s Inside the Folder?<\/strong><br>Your project folder contains several files and directories:\n<ul class=\"wp-block-list\">\n<li>A\u00a0<code>node_modules<\/code>\u00a0folder with all the dependencies installed for your project.<\/li>\n\n\n\n<li>A\u00a0<code>public<\/code>\u00a0folder that includes static assets like the\u00a0<code>index.html<\/code>\u00a0file.<\/li>\n\n\n\n<li>A\u00a0<code>src<\/code>\u00a0folder, which is the main location for your React components and logic.<\/li>\n\n\n\n<li>A\u00a0<code>package.json<\/code>\u00a0file, which lists project metadata and dependencies.<\/li>\n\n\n\n<li>A\u00a0<code>README.md<\/code>\u00a0file, which contains instructions and information about your project.<\/li>\n<\/ul>\n<\/li>\n<\/ol>\n\n\n\n<p>At this stage, your new React application is ready, and you\u2019re set to begin building your project.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\"><a href=\"https:\/\/lichess.org\/@\/HollowLeaf\/blog\/chess-web-programming-part-eight-chesscom-api\/mGHcVFEJ#open-the-project-in-vs-code\"><\/a>Open the Project in VS Code<\/h2>\n\n\n\n<p>Once your React application is created, the next step is to open it in a code editor. We\u2019ll use&nbsp;<strong>Visual Studio Code (VS Code)<\/strong>, a popular editor for web development.<\/p>\n\n\n\n<ol class=\"wp-block-list\">\n<li><strong>Launch VS Code<\/strong><br>Open Visual Studio Code from your operating system\u2019s application menu.<\/li>\n\n\n\n<li><strong>Add the Project Folder to Workspace<\/strong><br>In VS Code:<ul><li>Click on\u00a0<strong>File<\/strong>\u00a0in the top menu bar.<\/li><li>Select\u00a0<strong>Add Folder to Workspace<\/strong>.<\/li><li>In the file explorer that appears, navigate to the folder where you created your React project (<code>chessdotcom-api-app<\/code>).<\/li><li>Select the folder and click\u00a0<strong>Add<\/strong>.<\/li><\/ul>This step ensures that all files and folders in your project are accessible from within VS Code.<\/li>\n\n\n\n<li><strong>Explore the Workspace<\/strong><br>Once the folder is added, you\u2019ll see the project structure in the VS Code\u00a0<strong>Explorer<\/strong>\u00a0panel on the left. Key elements include:\n<ul class=\"wp-block-list\">\n<li><strong><code>src<\/code>\u00a0folder<\/strong>: This is where you\u2019ll write your React code.<\/li>\n\n\n\n<li><strong><code>public<\/code>\u00a0folder<\/strong>: Contains the\u00a0<code>index.html<\/code>\u00a0file, where your React application is injected.<\/li>\n\n\n\n<li><strong><code>package.json<\/code><\/strong>: Lists project dependencies and configuration.<\/li>\n<\/ul>\n<\/li>\n\n\n\n<li><strong>Open the Terminal in VS Code<\/strong><br>To run commands directly from VS Code:\n<ul class=\"wp-block-list\">\n<li>Go to the top menu and select\u00a0<strong>View<\/strong>\u00a0<strong>Terminal<\/strong>.<\/li>\n\n\n\n<li>A terminal window will open at the bottom of the editor, starting in your project folder.<\/li>\n<\/ul>\n<\/li>\n\n\n\n<li><strong>Verify Everything is Set Up<\/strong><br>In the terminal, start the development server by typing\u00a0<code>npm start<\/code>. This will run your React application and open it in your default web browser at\u00a0<code>http:\/\/localhost:3000<\/code>.<br>If you see the default React welcome page in your browser, everything is set up correctly.<\/li>\n<\/ol>\n\n\n\n<blockquote class=\"wp-block-quote is-layout-flow wp-block-quote-is-layout-flow\">\n<p><strong>Note:<\/strong>&nbsp;If you have another server running on your machine (for example, another React project), you may encounter a message like:<br><em>&#8220;Something is already running on port 3000.&#8221;<\/em><br>In this case, you will be given two options:<\/p>\n\n\n\n<ol class=\"wp-block-list\">\n<li><strong>Use a Different Port<\/strong>: React will prompt you to run the application on a different port, such as\u00a0<code>http:\/\/localhost:3001<\/code>. You can press\u00a0<code>Y<\/code>\u00a0to confirm.<\/li>\n\n\n\n<li><strong>Shut Down the Other Server<\/strong>: If you prefer to run your application on port 3000, you\u2019ll need to stop the other server. To do this, go to the terminal where the other server is running and press\u00a0<code>Ctrl + C<\/code>\u00a0(or\u00a0<code>Cmd + C<\/code>\u00a0on macOS) to terminate it.<\/li>\n<\/ol>\n<\/blockquote>\n\n\n\n<h2 class=\"wp-block-heading\"><a href=\"https:\/\/lichess.org\/@\/HollowLeaf\/blog\/chess-web-programming-part-eight-chesscom-api\/mGHcVFEJ#introducing-material-ui\"><\/a>Introducing Material UI<\/h2>\n\n\n\n<p>In this section, we\u2019ll enhance the user interface of our React application using&nbsp;<strong>Material UI<\/strong>, a popular library of pre-styled and customizable components. Material UI allows us to quickly build professional, modern-looking interfaces without having to write extensive CSS. By the end of this section, we\u2019ll have a clean and responsive form with the following features:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>An input field for the\u00a0<strong>Chess.com username<\/strong>.<\/li>\n\n\n\n<li>Input fields for the\u00a0<strong>Year<\/strong>\u00a0and\u00a0<strong>Month<\/strong>.<\/li>\n\n\n\n<li>A button to\u00a0<strong>trigger the API call<\/strong>\u00a0and fetch the games.<\/li>\n<\/ul>\n\n\n\n<p>This form will lay the groundwork for integrating the Chess.com API in the next section.<\/p>\n\n\n\n<h4 class=\"wp-block-heading\"><a href=\"https:\/\/lichess.org\/@\/HollowLeaf\/blog\/chess-web-programming-part-eight-chesscom-api\/mGHcVFEJ#why-use-material-ui\"><\/a>Why Use Material UI?<\/h4>\n\n\n\n<p>Material UI (MUI) is based on Google\u2019s Material Design principles, focusing on clean, consistent, and user-friendly interfaces. Here are some reasons to use it:<\/p>\n\n\n\n<ol class=\"wp-block-list\">\n<li><strong>Pre-Styled Components<\/strong>: Includes a library of pre-designed components like buttons, tables, and input fields.<\/li>\n\n\n\n<li><strong>Customizability<\/strong>: You can easily tweak the styles using inline styling, theming, or CSS overrides.<\/li>\n\n\n\n<li><strong>Accessibility<\/strong>: Material UI components are built with accessibility in mind, making your application more user-friendly.<\/li>\n\n\n\n<li><strong>Ease of Use<\/strong>: You can achieve professional designs with minimal effort, reducing the need to write custom CSS.<\/li>\n<\/ol>\n\n\n\n<p>By using Material UI, we can focus more on building the application logic rather than spending time on UI design from scratch.<\/p>\n\n\n\n<h4 class=\"wp-block-heading\"><a href=\"https:\/\/lichess.org\/@\/HollowLeaf\/blog\/chess-web-programming-part-eight-chesscom-api\/mGHcVFEJ#step-1-install-material-ui\"><\/a>Step 1: Install Material UI<\/h4>\n\n\n\n<p>To begin using Material UI, we need to install the required packages. These include:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li><strong><code>[@mui](\/@\/mui)\/material<\/code><\/strong>: The core Material UI component library.<\/li>\n\n\n\n<li><strong><code>[@emotion](\/@\/emotion)\/react<\/code><\/strong>\u00a0and\u00a0<strong><code>[@emotion](\/@\/emotion)\/styled<\/code><\/strong>: Required for styling the Material UI components.<\/li>\n<\/ul>\n\n\n\n<p>Install these packages by running the following command in your terminal:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>npm install &#91;@mui](\/@\/mui)\/material &#91;@emotion](\/@\/emotion)\/react &#91;@emotion](\/@\/emotion)\/styled<\/code><\/pre>\n\n\n\n<p>The&nbsp;<code>[@emotion](\/@\/emotion)\/react<\/code>&nbsp;and&nbsp;<code>[@emotion](\/@\/emotion)\/styled<\/code>&nbsp;packages are necessary for Material UI\u2019s styling to work. Once installed, you can start using Material UI components in your project.<\/p>\n\n\n\n<h4 class=\"wp-block-heading\"><a href=\"https:\/\/lichess.org\/@\/HollowLeaf\/blog\/chess-web-programming-part-eight-chesscom-api\/mGHcVFEJ#step-2-create-the-basic-form\"><\/a>Step 2: Create the Basic Form<\/h4>\n\n\n\n<p>Now, we\u2019ll set up a basic form in&nbsp;<code>App.js<\/code>&nbsp;with:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>An input field for the Chess.com username.<\/li>\n\n\n\n<li>An input field for the year and month.<\/li>\n\n\n\n<li>A button to fetch games.<\/li>\n<\/ul>\n\n\n\n<p>Replace the content of&nbsp;<code>src\/App.js<\/code>&nbsp;with the following:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>import React, { useState } from 'react';\nimport { TextField, Button, Container, Typography, Box } from '&#91;@mui](\/@\/mui)\/material';\n\nfunction App() {\n  const &#91;username, setUsername] = useState(''); \/\/ State to store the Chess.com username\n  const &#91;year, setYear] = useState(new Date().getFullYear()); \/\/ State to store the year, defaults to the current year\n  const &#91;month, setMonth] = useState(new Date().getMonth() + 1); \/\/ State to store the month, defaults to the current month\n\n  \/\/ Function to handle the fetching of games\n  const fetchGames = () => {\n    console.log(`Fetching games for ${username} from ${year}-${month}`); \/\/ Logs the form values to the console\n  };\n\n  return (\n    &lt;Container>\n      {\/* Title for the application *\/}\n      &lt;Typography variant=\"h4\" gutterBottom>\n        Chess.com Game Fetcher\n      &lt;\/Typography>\n\n      {\/* Container for inputs and button aligned in a row *\/}\n      &lt;Box display=\"flex\" justifyContent=\"flex-start\" alignItems=\"center\" gap={2} style={{ marginTop: '20px' }}>\n        {\/* Input for Chess.com username *\/}\n        &lt;TextField\n          label=\"Chess.com Username\"\n          variant=\"outlined\"\n          value={username}\n          onChange={(e) => setUsername(e.target.value)} \/\/ Updates the username state\n        \/>\n\n        {\/* Input for year *\/}\n        &lt;TextField\n          label=\"Year\"\n          variant=\"outlined\"\n          type=\"number\"\n          value={year}\n          onChange={(e) => setYear(e.target.value)} \/\/ Updates the year state\n        \/>\n\n        {\/* Input for month *\/}\n        &lt;TextField\n          label=\"Month\"\n          variant=\"outlined\"\n          type=\"number\"\n          value={month}\n          onChange={(e) => setMonth(e.target.value)} \/\/ Updates the month state\n        \/>\n\n        {\/* Button to fetch games *\/}\n        &lt;Button\n          variant=\"contained\"\n          color=\"primary\"\n          onClick={fetchGames} \/\/ Calls fetchGames when clicked\n        >\n          Fetch Games\n        &lt;\/Button>\n      &lt;\/Box>\n    &lt;\/Container>\n  );\n}\n\nexport default App;<\/code><\/pre>\n\n\n\n<h4 class=\"wp-block-heading\"><a href=\"https:\/\/lichess.org\/@\/HollowLeaf\/blog\/chess-web-programming-part-eight-chesscom-api\/mGHcVFEJ#step-3-understanding-the-code\"><\/a>Step 3: Understanding the Code<\/h4>\n\n\n\n<ul class=\"wp-block-list\">\n<li><strong>Container<\/strong>: A Material UI layout component that centers content and adds padding.<\/li>\n\n\n\n<li><strong>Typography<\/strong>: Styles text elements like headings. Used for the title &#8220;Chess.com Game Fetcher.&#8221;<\/li>\n\n\n\n<li><strong>TextField<\/strong>: Input components for:\n<ul class=\"wp-block-list\">\n<li>Chess.com username.<\/li>\n\n\n\n<li>Year (defaults to the current year).<\/li>\n\n\n\n<li>Month (defaults to the current month).<\/li>\n<\/ul>\n<\/li>\n\n\n\n<li><strong>Button<\/strong>: Triggers the\u00a0<code>fetchGames<\/code>\u00a0function when clicked.<\/li>\n\n\n\n<li><strong>useState Hooks<\/strong>:\n<ul class=\"wp-block-list\">\n<li><code>username<\/code>: Stores the entered Chess.com username.<\/li>\n\n\n\n<li><code>year<\/code>: Stores the year for the game archive.<\/li>\n\n\n\n<li><code>month<\/code>: Stores the month for the game archive.<\/li>\n<\/ul>\n<\/li>\n\n\n\n<li><strong>fetchGames Function<\/strong>: Logs the entered\u00a0<code>username<\/code>,\u00a0<code>year<\/code>, and\u00a0<code>month<\/code>\u00a0values to the console. Will later fetch data from the Chess.com API.<\/li>\n<\/ul>\n\n\n\n<h4 class=\"wp-block-heading\"><a href=\"https:\/\/lichess.org\/@\/HollowLeaf\/blog\/chess-web-programming-part-eight-chesscom-api\/mGHcVFEJ#step-4-preview-the-form\"><\/a>Step 4: Preview the Form<\/h4>\n\n\n\n<p>Save your changes and check the browser. You should see:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>A title labeled \u201cChess.com Game Fetcher.\u201d<\/li>\n\n\n\n<li>Three input fields for the username, year and month.<\/li>\n\n\n\n<li>A button labeled \u201cFetch Games.\u201d<\/li>\n<\/ul>\n\n\n\n<p><img decoding=\"async\" src=\"https:\/\/image.lichess1.org\/display?fmt=webp&amp;h=0&amp;op=resize&amp;path=hollowleaf:ublogBody:MHA6vSuziiOc:VjfMUiAr.png&amp;w=800&amp;sig=2c9aff0bc4a712d968d0f0383f8ed654560ec5bd\" alt=\"image.png\"><br>At this stage, you\u2019ve built a functional form using Material UI. In the next section, we\u2019ll connect this form to the Chess.com API to fetch and display game data.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\"><a href=\"https:\/\/lichess.org\/@\/HollowLeaf\/blog\/chess-web-programming-part-eight-chesscom-api\/mGHcVFEJ#fetching-and-displaying-games\"><\/a>Fetching and Displaying Games<\/h2>\n\n\n\n<p>In this section, we\u2019ll integrate the Chess.com API into our React application. The goal is to fetch a list of chess games for a specific player, process the data to extract essential details, and display the information in a structured format using a Material UI Table.<br>We\u2019ll also learn how to clean PGN (Portable Game Notation) data to extract bare moves without metadata, comments, or move numbers for a clean display.<\/p>\n\n\n\n<h4 class=\"wp-block-heading\"><a href=\"https:\/\/lichess.org\/@\/HollowLeaf\/blog\/chess-web-programming-part-eight-chesscom-api\/mGHcVFEJ#step-1-understand-the-chesscom-api-endpoint\"><\/a>Step 1: Understand the Chess.com API Endpoint<\/h4>\n\n\n\n<p>The Chess.com API provides access to historical game data for users. The endpoint we\u2019re using retrieves monthly games for a specified player.<br><strong>Endpoint:<\/strong><\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>https:&#47;&#47;api.chess.com\/pub\/player\/{username}\/games\/{year}\/{month}<\/code><\/pre>\n\n\n\n<p><strong>Key Parameters:<\/strong><\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li><code>{username}<\/code>: The Chess.com username.<\/li>\n\n\n\n<li><code>{year}<\/code>\u00a0and\u00a0<code>{month}<\/code>: The year and month for the games to fetch.<\/li>\n<\/ul>\n\n\n\n<p>The response includes metadata (like players&#8217; ratings and results) and the full PGN for each game.<\/p>\n\n\n\n<h4 class=\"wp-block-heading\"><a href=\"https:\/\/lichess.org\/@\/HollowLeaf\/blog\/chess-web-programming-part-eight-chesscom-api\/mGHcVFEJ#step-2-fetch-games-from-the-chesscom-api\"><\/a>Step 2: Fetch Games from the Chess.com API<\/h4>\n\n\n\n<p>To fetch the data, we\u2019ll:<\/p>\n\n\n\n<ol class=\"wp-block-list\">\n<li>Dynamically construct the API URL based on user input (username, year, and month).<\/li>\n\n\n\n<li>Use the Fetch API to make a GET request.<\/li>\n\n\n\n<li>Parse the JSON response and store the games in a state variable.<\/li>\n<\/ol>\n\n\n\n<p>Here\u2019s the function:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>const fetchGames = async () => {\n  if (!username || !year || !month) {\n    alert(\"Please provide a username, year, and month.\"); \/\/ Validate input.\n    return;\n  }\n\n  \/\/ Construct the API URL dynamically based on input\n  const url = `https:\/\/api.chess.com\/pub\/player\/${username}\/games\/${year}\/${month}`;\n\n  try {\n    const response = await fetch(url); \/\/ Fetch data from Chess.com API\n    const data = await response.json(); \/\/ Parse the JSON response\n\n    if (data.games) {\n      setGames(data.games); \/\/ Store the games in the state if available\n    } else {\n      alert(\"No games found for the specified period.\");\n    }\n  } catch (error) {\n    console.error(\"Error fetching games:\", error); \/\/ Log any errors\n    alert(\"Failed to fetch games. Please try again.\");\n  }\n};<\/code><\/pre>\n\n\n\n<h4 class=\"wp-block-heading\"><a href=\"https:\/\/lichess.org\/@\/HollowLeaf\/blog\/chess-web-programming-part-eight-chesscom-api\/mGHcVFEJ#step-3-extract-bare-moves-from-pgn\"><\/a>Step 3: Extract Bare Moves from PGN<\/h4>\n\n\n\n<p>The PGN data often includes metadata, move numbers, and comments, which can clutter the display. To clean this data, we\u2019ll use the following function to extract only the moves:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>const extractMoves = (pgn) => {\n  \/\/ Remove metadata lines (lines that start with &#91; and end with ])\n  const noMetadata = pgn.replace(\/^\\&#91;.*\\]$\/gm, '');\n\n  \/\/ Remove comments inside {}\n  const noComments = noMetadata.replace(\/\\{.*?\\}\/g, '');\n\n  \/\/ Remove move numbers (e.g., \"1.\", \"1...\")\n  const noMoveNumbers = noComments.replace(\/\\d+\\.+\/g, '');\n\n  \/\/ Clean up extra spaces and return\n  return noMoveNumbers.trim().replace(\/\\s+\/g, ' '); \/\/ Replace multiple spaces with a single space\n};<\/code><\/pre>\n\n\n\n<p>This function ensures that only the bare moves are displayed in a clean, human-readable format.<\/p>\n\n\n\n<h4 class=\"wp-block-heading\"><a href=\"https:\/\/lichess.org\/@\/HollowLeaf\/blog\/chess-web-programming-part-eight-chesscom-api\/mGHcVFEJ#step-4-display-games-in-a-table\"><\/a>Step 4: Display Games in a Table<\/h4>\n\n\n\n<p>We\u2019ll use Material UI\u2019s Table component to display the fetched games. Each row will represent a single game, showing key details like the players, results, and bare moves.<br>Here\u2019s the code:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>&lt;Table>\n  &lt;TableHead>\n    &lt;TableRow>\n      &lt;TableCell>White&lt;\/TableCell> {\/* Column for the White player's name and rating *\/}\n      &lt;TableCell>Black&lt;\/TableCell> {\/* Column for the Black player's name and rating *\/}\n      &lt;TableCell>Result&lt;\/TableCell> {\/* Column for the game result *\/}\n      &lt;TableCell>Moves&lt;\/TableCell> {\/* Column for the extracted moves *\/}\n    &lt;\/TableRow>\n  &lt;\/TableHead>\n  &lt;TableBody>\n    {games.map((game, index) => (\n      &lt;TableRow key={index}> {\/* Unique key for each row *\/}\n        {\/* White player details *\/}\n        &lt;TableCell>\n          {game.white.username} ({game.white.rating})\n        &lt;\/TableCell>\n        {\/* Black player details *\/}\n        &lt;TableCell>\n          {game.black.username} ({game.black.rating})\n        &lt;\/TableCell>\n        {\/* Game result *\/}\n        &lt;TableCell>\n          {game.white.result === \"win\"\n            ? \"White Wins\"\n            : game.black.result === \"win\"\n            ? \"Black Wins\"\n            : \"Draw\"}\n        &lt;\/TableCell>\n        {\/* Extracted moves *\/}\n        &lt;TableCell>\n          &lt;pre style={{ whiteSpace: \"pre-wrap\", wordWrap: \"break-word\" }}>\n            {extractMoves(game.pgn)} {\/* Display the clean moves *\/}\n          &lt;\/pre>\n        &lt;\/TableCell>\n      &lt;\/TableRow>\n    ))}\n  &lt;\/TableBody>\n&lt;\/Table><\/code><\/pre>\n\n\n\n<h4 class=\"wp-block-heading\"><a href=\"https:\/\/lichess.org\/@\/HollowLeaf\/blog\/chess-web-programming-part-eight-chesscom-api\/mGHcVFEJ#final-code\"><\/a>Final Code<\/h4>\n\n\n\n<p>Here\u2019s the complete implementation:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>import React, { useState } from \"react\";\nimport {\n  TextField,\n  Button,\n  Container,\n  Typography,\n  Box,\n  Table,\n  TableBody,\n  TableCell,\n  TableHead,\n  TableRow,\n} from \"&#91;@mui](\/@\/mui)\/material\";\n\nfunction App() {\n  const &#91;username, setUsername] = useState(\"\"); \/\/ State for the username input\n  const &#91;year, setYear] = useState(\"\"); \/\/ State for the year input\n  const &#91;month, setMonth] = useState(\"\"); \/\/ State for the month input\n  const &#91;games, setGames] = useState(&#91;]); \/\/ State to store fetched games\n\n  \/\/ Fetch games from the Chess.com API\n  const fetchGames = async () => {\n    if (!username || !year || !month) {\n      alert(\"Please provide a username, year, and month.\"); \/\/ Validate input\n      return;\n    }\n\n    const url = `https:\/\/api.chess.com\/pub\/player\/${username}\/games\/${year}\/${month}`;\n\n    try {\n      const response = await fetch(url); \/\/ Fetch data from Chess.com API\n      const data = await response.json(); \/\/ Parse the JSON response\n\n      if (data.games) {\n        setGames(data.games); \/\/ Store the games in the state if available\n      } else {\n        alert(\"No games found for the specified period.\");\n      }\n    } catch (error) {\n      console.error(\"Error fetching games:\", error); \/\/ Log errors\n      alert(\"Failed to fetch games. Please try again.\");\n    }\n  };\n\n  \/\/ Function to clean and extract bare moves from PGN\n  const extractMoves = (pgn) => {\n    const noMetadata = pgn.replace(\/^\\&#91;.*\\]$\/gm, ''); \/\/ Remove metadata\n    const noComments = noMetadata.replace(\/\\{.*?\\}\/g, ''); \/\/ Remove comments\n    const noMoveNumbers = noComments.replace(\/\\d+\\.+\/g, ''); \/\/ Remove move numbers\n    return noMoveNumbers.trim().replace(\/\\s+\/g, ' '); \/\/ Clean up extra spaces\n  };\n\n  return (\n    &lt;Container>\n      &lt;Typography variant=\"h4\" gutterBottom>\n        Chess.com Game Viewer\n      &lt;\/Typography>\n\n      {\/* Input Form *\/}\n      &lt;Box display=\"flex\" gap=\"16px\" marginBottom=\"20px\">\n        &lt;TextField\n          label=\"Username\"\n          value={username}\n          onChange={(e) => setUsername(e.target.value)}\n        \/>\n        &lt;TextField\n          label=\"Year\"\n          value={year}\n          onChange={(e) => setYear(e.target.value)}\n        \/>\n        &lt;TextField\n          label=\"Month\"\n          value={month}\n          onChange={(e) => setMonth(e.target.value)}\n        \/>\n        &lt;Button variant=\"contained\" onClick={fetchGames}>\n          Fetch Games\n        &lt;\/Button>\n      &lt;\/Box>\n\n      {\/* Games Table *\/}\n      {games.length > 0 &amp;&amp; (\n        &lt;Table>\n          &lt;TableHead>\n            &lt;TableRow>\n              &lt;TableCell>White&lt;\/TableCell>\n              &lt;TableCell>Black&lt;\/TableCell>\n              &lt;TableCell>Result&lt;\/TableCell>\n              &lt;TableCell>Moves&lt;\/TableCell>\n            &lt;\/TableRow>\n          &lt;\/TableHead>\n          &lt;TableBody>\n            {games.map((game, index) => (\n              &lt;TableRow key={index}>\n                &lt;TableCell>\n                  {game.white.username} ({game.white.rating})\n                &lt;\/TableCell>\n                &lt;TableCell>\n                  {game.black.username} ({game.black.rating})\n                &lt;\/TableCell>\n                &lt;TableCell>\n                  {game.white.result === \"win\"\n                    ? \"White Wins\"\n                    : game.black.result === \"win\"\n                    ? \"Black Wins\"\n                    : \"Draw\"}\n                &lt;\/TableCell>\n                &lt;TableCell>\n                  &lt;pre style={{ whiteSpace: \"pre-wrap\", wordWrap: \"break-word\" }}>\n                    {extractMoves(game.pgn)}\n                  &lt;\/pre>\n                &lt;\/TableCell>\n              &lt;\/TableRow>\n            ))}\n          &lt;\/TableBody>\n        &lt;\/Table>\n      )}\n    &lt;\/Container>\n  );\n}\n\nexport default App;<\/code><\/pre>\n\n\n\n<p>Explanation:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>The app allows users to fetch chess games from Chess.com by entering a username, year, and month.<\/li>\n\n\n\n<li>It uses React&#8217;s\u00a0<code>useState<\/code>\u00a0to manage user inputs and the fetched game data dynamically.<\/li>\n\n\n\n<li>A\u00a0<code>fetchGames<\/code>\u00a0function retrieves games from Chess.com&#8217;s API, constructs the API URL based on user inputs, and handles errors gracefully.<\/li>\n\n\n\n<li>The\u00a0<code>extractMoves<\/code>\u00a0function processes the game&#8217;s PGN (Portable Game Notation) to extract and clean just the chess moves, removing metadata, comments, and move numbers.<\/li>\n\n\n\n<li>The interface is built with Material UI, featuring input fields for user data, a fetch button, and a table for displaying the results.<\/li>\n\n\n\n<li>The games are displayed in a structured table, showing details like players, their ratings, the game result, and the extracted chess moves.<\/li>\n\n\n\n<li>The app dynamically updates and displays game data based on user input, providing a clean, responsive user experience.<\/li>\n<\/ul>\n\n\n\n<p>You should now see the following:<img decoding=\"async\" src=\"https:\/\/image.lichess1.org\/display?fmt=webp&amp;h=0&amp;op=resize&amp;path=hollowleaf:ublogBody:v1KON5ABsr0l:S8h2qPlH.png&amp;w=800&amp;sig=e0f60d2ea2386b423c8523722390a254888c1cc7\" alt=\"image.png\"><\/p>\n\n\n\n<h2 class=\"wp-block-heading\"><a href=\"https:\/\/lichess.org\/@\/HollowLeaf\/blog\/chess-web-programming-part-eight-chesscom-api\/mGHcVFEJ#formatting-our-output\"><\/a>Formatting Our Output<\/h2>\n\n\n\n<p>In this section, we\u2019ll enhance the game viewer by integrating key features into our app. These include rendering chessboards with the final game positions using&nbsp;<code>react-chessboard<\/code>, extracting moves, and adding detailed game data.<\/p>\n\n\n\n<h4 class=\"wp-block-heading\"><a href=\"https:\/\/lichess.org\/@\/HollowLeaf\/blog\/chess-web-programming-part-eight-chesscom-api\/mGHcVFEJ#key-goals\"><\/a>Key Goals:<\/h4>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Use\u00a0<code>react-chessboard<\/code>\u00a0to display the final position of games.<\/li>\n\n\n\n<li>Extract clean move sequences from PGN files.<\/li>\n\n\n\n<li>Enhance the game table with FEN-calculated chessboards and game details.<\/li>\n<\/ul>\n\n\n\n<h3 class=\"wp-block-heading\"><a href=\"https:\/\/lichess.org\/@\/HollowLeaf\/blog\/chess-web-programming-part-eight-chesscom-api\/mGHcVFEJ#step-1-install-required-libraries\"><\/a>Step 1: Install Required Libraries<\/h3>\n\n\n\n<p>To achieve our goals, we need two additional libraries:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li><code>react-chessboard<\/code>\u00a0for rendering the chessboard.<\/li>\n\n\n\n<li><code>chess.js<\/code>\u00a0for calculating the FEN (Forsyth-Edwards Notation) of a game from its moves.<\/li>\n<\/ul>\n\n\n\n<p>Install both libraries with the following command:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>npm install react-chessboard chess.js<\/code><\/pre>\n\n\n\n<p>After installation, import the required components into your file:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>import { Chessboard } from \"react-chessboard\"; \/\/ For chessboard rendering\nimport { Chess } from \"chess.js\"; \/\/ For FEN calculation<\/code><\/pre>\n\n\n\n<h3 class=\"wp-block-heading\"><a href=\"https:\/\/lichess.org\/@\/HollowLeaf\/blog\/chess-web-programming-part-eight-chesscom-api\/mGHcVFEJ#step-2-calculate-fen-from-pgn\"><\/a>Step 2: Calculate FEN from PGN<\/h3>\n\n\n\n<p>The&nbsp;<code>calculateFenFromMoves<\/code>&nbsp;function takes a PGN (Portable Game Notation) string, cleans it to extract moves, and uses&nbsp;<code>chess.js<\/code>&nbsp;to compute the FEN of the final position. This FEN is used to render the chessboard.<br>Here\u2019s the function:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>const calculateFenFromMoves = (pgn) => {\n  const chess = new Chess(); \/\/ Initialize a new Chess.js instance\n  const cleanMoves = extractMoves(pgn); \/\/ Extract clean moves from PGN (previously defined)\n  chess.loadPgn(cleanMoves); \/\/ Load moves into Chess.js\n  return chess.fen(); \/\/ Return the FEN of the final position\n};<\/code><\/pre>\n\n\n\n<h3 class=\"wp-block-heading\"><a href=\"https:\/\/lichess.org\/@\/HollowLeaf\/blog\/chess-web-programming-part-eight-chesscom-api\/mGHcVFEJ#step-3-fetch-games-and-limit-results\"><\/a>Step 3: Fetch Games and Limit Results<\/h3>\n\n\n\n<p>We\u2019ll update the&nbsp;<code>fetchGames<\/code>&nbsp;function to:<\/p>\n\n\n\n<ol class=\"wp-block-list\">\n<li>Fetch games from the Chess.com API.<\/li>\n\n\n\n<li>Calculate the FEN for each game\u2019s final position.<\/li>\n\n\n\n<li>Limit the number of games displayed to the first 50 for performance.<\/li>\n\n\n\n<li>Handle invalid games gracefully by skipping them. (This will handle the cases where you start the game from a specific position)<\/li>\n<\/ol>\n\n\n\n<p>Here\u2019s the updated function:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>const fetchGames = async () => {\n  if (!username || !month || !year) {\n    alert(\"Please provide username, year, and month.\"); \/\/ Validate inputs\n    return;\n  }\n\n  const url = `https:\/\/api.chess.com\/pub\/player\/${username}\/games\/${year}\/${month}`;\n\n  try {\n    const response = await fetch(url); \/\/ Fetch games from Chess.com API\n    const data = await response.json(); \/\/ Parse JSON response\n\n    const gamesWithFen = (data.games || &#91;])\n      .slice(0, 50) \/\/ Limit to the first 50 games\n      .reduce((acc, game) => {\n        try {\n          const finalFen = calculateFenFromMoves(game.pgn); \/\/ Calculate FEN\n          acc.push({\n            ...game,\n            finalFen, \/\/ Attach FEN to the game object\n          });\n        } catch (error) {\n          console.warn(`Skipping invalid game with PGN: ${game.pgn}`, error); \/\/ Skip invalid games\n        }\n        return acc;\n      }, &#91;]);\n\n    setGames(gamesWithFen); \/\/ Update state with valid games\n  } catch (error) {\n    console.error(\"Error fetching games:\", error); \/\/ Log fetch errors\n    alert(\"Failed to fetch games. Please try again.\");\n  }\n};<\/code><\/pre>\n\n\n\n<h3 class=\"wp-block-heading\"><a href=\"https:\/\/lichess.org\/@\/HollowLeaf\/blog\/chess-web-programming-part-eight-chesscom-api\/mGHcVFEJ#step-4-update-the-game-table\"><\/a>Step 4: Update the Game Table<\/h3>\n\n\n\n<p>We\u2019ll now display the fetched games in a table. Each row will show:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>A chessboard displaying the game\u2019s final position.<\/li>\n\n\n\n<li>Game details, including players, ratings, results, date, and move list.<\/li>\n<\/ul>\n\n\n\n<p>Here\u2019s the code to render the table:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>{games.length > 0 &amp;&amp; (\n  &lt;Table sx={{ marginTop: 3 }}>\n    &lt;TableBody>\n      {games.map((game, index) => (\n        &lt;TableRow key={index}>\n          {\/* Chessboard Column *\/}\n          &lt;TableCell>\n            &lt;Chessboard\n              position={game.finalFen || \"start\"} \/\/ Display final position or default to start\n              arePiecesDraggable={false} \/\/ Disable piece dragging\n              boardWidth={200} \/\/ Set board size\n            \/>\n          &lt;\/TableCell>\n\n          {\/* Game Details Column *\/}\n          &lt;TableCell>\n            &lt;Box sx={{ display: \"flex\", flexDirection: \"column\", gap: 1 }}>\n              &lt;Typography variant=\"h6\">\n                {game.white.username || \"Anonymous\"} ({game.white.rating}) vs{\" \"}\n                {game.black.username || \"Anonymous\"} ({game.black.rating})\n              &lt;\/Typography>\n              &lt;Typography variant=\"body1\">\n                Result:{\" \"}\n                {game.white.result === \"win\"\n                  ? \"White Wins\"\n                  : game.black.result === \"win\"\n                  ? \"Black Wins\"\n                  : \"Draw\"}\n              &lt;\/Typography>\n              &lt;Typography variant=\"body2\">\n                Date: {new Date(game.end_time * 1000).toLocaleString()}\n              &lt;\/Typography>\n              &lt;Typography variant=\"body2\" sx={{ whiteSpace: \"pre-wrap\" }}>\n                Moves: {extractMoves(game.pgn)}\n              &lt;\/Typography>\n            &lt;\/Box>\n          &lt;\/TableCell>\n        &lt;\/TableRow>\n      ))}\n    &lt;\/TableBody>\n  &lt;\/Table>\n)}<\/code><\/pre>\n\n\n\n<h3 class=\"wp-block-heading\"><a href=\"https:\/\/lichess.org\/@\/HollowLeaf\/blog\/chess-web-programming-part-eight-chesscom-api\/mGHcVFEJ#final-code-1\"><\/a>Final Code<\/h3>\n\n\n\n<p>Here\u2019s the complete app code after implementing all steps:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>import React, { useState } from \"react\";\nimport {\n  TextField,\n  Button,\n  Container,\n  Typography,\n  Box,\n  Table,\n  TableBody,\n  TableCell,\n  TableRow,\n} from \"&#91;@mui](\/@\/mui)\/material\";\nimport { Chess } from \"chess.js\";\nimport { Chessboard } from \"react-chessboard\";\n\n\/\/ Function to clean and extract bare moves from PGN\nconst extractMoves = (pgn) => {\n  const noMetadata = pgn.replace(\/^\\&#91;.*\\]$\/gm, \"\"); \/\/ Remove metadata\n  const noComments = noMetadata.replace(\/\\{.*?\\}\/g, \"\"); \/\/ Remove comments\n  const noMoveNumbers = noComments.replace(\/\\d+\\.+\/g, \"\"); \/\/ Remove move numbers\n  return noMoveNumbers.trim().replace(\/\\s+\/g, \" \"); \/\/ Clean up extra spaces\n};\n\n\/\/ Function to calculate FEN from moves\nconst calculateFenFromMoves = (pgn) => {\n  const chess = new Chess(); \/\/ Initialize Chess.js instance\n  const cleanMoves = extractMoves(pgn); \/\/ Extract clean moves (defined above)\n  chess.loadPgn(cleanMoves); \/\/ Load moves into Chess.js\n  return chess.fen(); \/\/ Return the FEN of the final position\n};\n\nfunction App() {\n  const &#91;username, setUsername] = useState(\"\");\n  const &#91;month, setMonth] = useState(\"\");\n  const &#91;year, setYear] = useState(\"\");\n  const &#91;games, setGames] = useState(&#91;]);\n\n  const fetchGames = async () => {\n    if (!username || !month || !year) {\n      alert(\"Please provide username, year, and month.\"); \/\/ Validate inputs\n      return;\n    }\n\n    const url = `https:\/\/api.chess.com\/pub\/player\/${username}\/games\/${year}\/${month}`;\n\n    try {\n      const response = await fetch(url); \/\/ Fetch games from Chess.com API\n      const data = await response.json(); \/\/ Parse JSON response\n\n      const gamesWithFen = (data.games || &#91;])\n        .slice(0, 50) \/\/ Limit to the first 50 games\n        .reduce((acc, game) => {\n          try {\n            const finalFen = calculateFenFromMoves(game.pgn); \/\/ Calculate FEN\n            acc.push({\n              ...game,\n              finalFen,\n            });\n          } catch (error) {\n            console.warn(`Skipping invalid game with PGN: ${game.pgn}`, error);\n          }\n          return acc;\n        }, &#91;]);\n\n      setGames(gamesWithFen); \/\/ Update state with valid games\n    } catch (error) {\n      console.error(\"Error fetching games:\", error); \/\/ Log fetch errors\n      alert(\"Failed to fetch games. Please try again.\");\n    }\n  };\n\n  return (\n    &lt;Container>\n      &lt;Typography variant=\"h4\" gutterBottom>\n        Chess.com Game Viewer\n      &lt;\/Typography>\n      &lt;Box sx={{ display: \"flex\", gap: 2, marginTop: 3 }}>\n        &lt;TextField\n          label=\"Username\"\n          value={username}\n          onChange={(e) => setUsername(e.target.value)}\n        \/>\n        &lt;TextField\n          label=\"Year\"\n          value={year}\n          onChange={(e) => setYear(e.target.value)}\n        \/>\n        &lt;TextField\n          label=\"Month\"\n          value={month}\n          onChange={(e) => setMonth(e.target.value)}\n        \/>\n        &lt;Button variant=\"contained\" onClick={fetchGames}>\n          Fetch Games\n        &lt;\/Button>\n      &lt;\/Box>\n      {games.length > 0 &amp;&amp; (\n        &lt;Table sx={{ marginTop: 3 }}>\n          &lt;TableBody>\n            {games.map((game, index) => (\n              &lt;TableRow key={index}>\n                &lt;TableCell>\n                  &lt;Chessboard\n                    position={game.finalFen || \"start\"}\n                    arePiecesDraggable={false}\n                    boardWidth={200}\n                  \/>\n                &lt;\/TableCell>\n                &lt;TableCell>\n                  &lt;Box sx={{ display: \"flex\", flexDirection: \"column\", gap: 1 }}>\n                    &lt;Typography variant=\"h6\">\n                      {game.white.username || \"Anonymous\"} ({game.white.rating})\n                      vs {game.black.username || \"Anonymous\"} (\n                      {game.black.rating})\n                    &lt;\/Typography>\n                    &lt;Typography variant=\"body1\">\n                      Result:{\" \"}\n                      {game.white.result === \"win\"\n                        ? \"White Wins\"\n                        : game.black.result === \"win\"\n                        ? \"Black Wins\"\n                        : \"Draw\"}\n                    &lt;\/Typography>\n                    &lt;Typography variant=\"body2\">\n                      Date: {new Date(game.end_time * 1000).toLocaleString()}\n                    &lt;\/Typography>\n                    &lt;Typography\n                      variant=\"body2\"\n                      sx={{ whiteSpace: \"pre-wrap\" }}\n                    >\n                      Moves: {extractMoves(game.pgn)}\n                    &lt;\/Typography>\n                  &lt;\/Box>\n                &lt;\/TableCell>\n              &lt;\/TableRow>\n            ))}\n          &lt;\/TableBody>\n        &lt;\/Table>\n      )}\n    &lt;\/Container>\n  );\n}\n\nexport default App;<\/code><\/pre>\n\n\n\n<p>Explanation:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li><strong>Chessboard Rendering:<\/strong>\u00a0Uses\u00a0<code>react-chessboard<\/code>\u00a0to display the final position of each game.<\/li>\n\n\n\n<li><strong>Move Extraction:<\/strong>\u00a0Extracts and cleans up moves from the PGN format.<\/li>\n\n\n\n<li><strong>FEN Calculation:<\/strong>\u00a0Utilizes\u00a0<code>chess.js<\/code>\u00a0to calculate the FEN for the final game position.<\/li>\n\n\n\n<li><strong>Error Handling:<\/strong>\u00a0Skips invalid games and logs a warning without stopping the app.<\/li>\n\n\n\n<li><strong>Game Table:<\/strong>\u00a0Displays a user-friendly table with chessboard visuals, player details, results, and moves.<\/li>\n<\/ul>\n\n\n\n<p>You should now see the following:<br><img decoding=\"async\" src=\"https:\/\/image.lichess1.org\/display?fmt=webp&amp;h=0&amp;op=resize&amp;path=hollowleaf:ublogBody:gJvhhpBJATxe:TLLjRoAz.png&amp;w=800&amp;sig=72c475e2c910deaa3f5624a3e4e89797c19f3887\" alt=\"image.png\"><\/p>\n\n\n\n<h2 class=\"wp-block-heading\"><a href=\"https:\/\/lichess.org\/@\/HollowLeaf\/blog\/chess-web-programming-part-eight-chesscom-api\/mGHcVFEJ#summary\"><\/a>Summary<\/h2>\n\n\n\n<p>In this blog, we dove into the fascinating intersection of chess and web development by building a React application powered by the Chess.com API. We began by understanding the API\u2019s capabilities and how it allows us to fetch detailed data about users&#8217; games. Leveraging this data, we developed an interactive application that displays user-specific chess games in a visually engaging and organized format.<br>Using&nbsp;<code>react-chessboard<\/code>, we rendered the final positions of games directly on the interface, while Material UI helped us structure and style the data for clarity and responsiveness. Our application features a two-column layout: one side displays the final position of each game on a chessboard, while the other provides detailed game information, including player names and ratings, game results, dates, and a list of moves extracted from the PGN. Along the way, we emphasized best practices, such as efficient data processing, robust error handling, and clean presentation.<br>This project demonstrates how to combine chess knowledge with modern web technologies to create a practical and aesthetically pleasing application. Whether you&#8217;re interested in building tools for game analysis, exploring educational chess applications, or creating personalized chess visualizations, the skills and techniques covered here serve as a strong foundation. The chessboard is just the start\u2014your creativity can take this application in countless exciting directions. Let your passion for chess and coding inspire your next project!<\/p>\n\n\n\n<h3 class=\"wp-block-heading\"><a href=\"https:\/\/lichess.org\/@\/HollowLeaf\/blog\/chess-web-programming-part-eight-chesscom-api\/mGHcVFEJ#learn-more\"><\/a>Learn More<\/h3>\n\n\n\n<p>Here are the tools and resources we used in this article to build our Lichess game viewer application. Each of these is essential for recreating and understanding the project:<\/p>\n\n\n\n<p><strong><a href=\"https:\/\/code.visualstudio.com\/\">Visual Studio Code<\/a><\/strong>: We used VS Code as our code editor throughout this project. It\u2019s a powerful tool for coding, debugging, and managing projects. Download it to streamline your development workflow.<a href=\"https:\/\/lichess.org\/@\/HollowLeaf\/blog\"><\/a><\/p>\n\n\n\n<p><strong><a href=\"https:\/\/lichess.org\/api\">Lichess API<\/a><\/strong>: The Lichess API is the backbone of this project, providing access to chess game data. Explore its extensive capabilities and learn how to fetch games, puzzles, and more.<\/p>\n\n\n\n<p><strong><a href=\"https:\/\/reactjs.org\/\">React<\/a><\/strong>: React is the framework we used to build this dynamic and interactive application. Learn how to create components, manage state, and build engaging user interfaces.<\/p>\n\n\n\n<p><strong><a href=\"https:\/\/mui.com\/\">Material UI<\/a><\/strong>: Material UI is the library we used to style the application and create components like tables, text fields, and buttons. Explore its components and theming options to enhance your React apps.<\/p>\n\n\n\n<p><strong><a href=\"https:\/\/github.com\/Clariity\/react-chessboard\">react-chessboard<\/a><\/strong>: This library allowed us to display the final position of games as a static chessboard. Learn how to use it to create visually appealing chessboard components in your applications.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Working with the Chess.com API My journey into programming chess applications started with&nbsp;Chessboard Magic, a personal project that turned into a platform with over 34 unique chess-based applications. This blog continues my&nbsp;Chess Web Programming&nbsp;series, diving into one of the most exciting aspects of modern development: working with APIs. In this installment, we\u2019ll explore the&nbsp;Chess.com API, [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":51,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[1],"tags":[],"class_list":["post-50","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-uncategorized"],"_links":{"self":[{"href":"https:\/\/blog.chessboardmagic.com\/index.php\/wp-json\/wp\/v2\/posts\/50","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/blog.chessboardmagic.com\/index.php\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/blog.chessboardmagic.com\/index.php\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/blog.chessboardmagic.com\/index.php\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/blog.chessboardmagic.com\/index.php\/wp-json\/wp\/v2\/comments?post=50"}],"version-history":[{"count":1,"href":"https:\/\/blog.chessboardmagic.com\/index.php\/wp-json\/wp\/v2\/posts\/50\/revisions"}],"predecessor-version":[{"id":52,"href":"https:\/\/blog.chessboardmagic.com\/index.php\/wp-json\/wp\/v2\/posts\/50\/revisions\/52"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/blog.chessboardmagic.com\/index.php\/wp-json\/wp\/v2\/media\/51"}],"wp:attachment":[{"href":"https:\/\/blog.chessboardmagic.com\/index.php\/wp-json\/wp\/v2\/media?parent=50"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/blog.chessboardmagic.com\/index.php\/wp-json\/wp\/v2\/categories?post=50"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/blog.chessboardmagic.com\/index.php\/wp-json\/wp\/v2\/tags?post=50"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}