Building a Custom Substrate Blockchain Frontend with React

Building a Custom Frontend for a Substrate-Based Blockchain with React

Blockchains Built with Substrate

Substrate is a framework for building custom blockchains. By default, blockchains built with Substrate provide an API for clients to connect for RPC calls, such as using WebSockets. The official recommended way to interact with any Substrate-based chain is to use Polkadot-JS.

Setting Up Substrate

To get started, we need to fork the Substrate Frontend Template repository and clone our fork. Then, we can navigate inside the directory and execute the command to install all the necessary dependencies and start the template on http://localhost:8000.


git clone https://github.com/your-username/substrate-frontend-template.git
cd substrate-frontend-template
npm install
npm start

Basic Components

We will build several custom components, including:

  • Blogchain: The top-level component that will contain the rest of our components.
  • blogchain/ListBlogPost: Component for listing blog posts and their details.
  • blogchain/CreateBlogPost: Form for adding a new blog post.
  • blogchain/CreateComment: Form for adding a new comment.
  • blogchain/Tip: Form for tipping a blog post author.

Form-Building Components

We will use Semantic UI’s built-in Form components to build our forms. We will also use the TxButton component from the substrate-lib bundle to interact with the blockchain.


import { Form, Button } from 'semantic-ui-react';
import { TxButton } from '@substrate-lib/components';

const CreateBlogPost = () => {
  const [title, setTitle] = useState('');
  const [content, setContent] = useState('');

  const handleSubmit = (event) => {
    event.preventDefault();
    // Interact with the blockchain using TxButton
  };

  return (
    <Form onSubmit={handleSubmit}>
      <Form.Field>
        <label>Title</label>
        <input type="text" value={title} onChange={(event) => setTitle(event.target.value)}>
      </Form.Field>
      <Form.Field>
        <label>Content</label>
        <textarea value={content} onChange={(event) => setContent(event.target.value)}></textarea>
      </Form.Field>
      <TxButton type="submit">Create Blog Post</TxButton>
    </Form>
  );
};

Fetching Data and Listing Blog Posts

To list our blog posts, we need to fetch both the blog posts and their comments, then render them.


import { useState, useEffect } from 'react';
import axios from 'axios';

const ListBlogPosts = () => {
  const [blogPosts, setBlogPosts] = useState([]);
  const [comments, setComments] = useState({});

  useEffect(() => {
    axios.get('/api/blog-posts')
      .then((response) => {
        setBlogPosts(response.data);
      })
      .catch((error) => {
        console.error(error);
      });

    axios.get('/api/comments')
      .then((response) => {
        setComments(response.data);
      })
      .catch((error) => {
        console.error(error);
      });
  }, []);

  return (
    <div>
      {blogPosts.map((blogPost) => (
        <div key={blogPost.id}>
          <h2>{blogPost.title}</h2>
          <p>{blogPost.content}</p>
          <h3>Comments:</h3>
          {comments[blogPost.id] && comments[blogPost.id].map((comment) => (
            <div key={comment.id}>
              <p>{comment.content}</p>
            </div>
          ))}
        </div>
      ))}
    </div>
  );
};

Leave a Reply

Your email address will not be published. Required fields are marked *