Let's jump in! Use the blocks-template as your starting point so you can focus on the fun parts of block development.
✨👉 Fork the template 👈✨
💡Alternatively, you can go to the blocks-template repository and click on the "Use this template" button on the top right of the repository to make a copy for your use.
Name your repository:
Finally, clone your newly-created repository, and you're ready to work.git clone <repo URL>
cd <repo name>
yarn # install dependencies
yarn start # start the dev serverA development server should now be running on localhost:4000.
When you visit localhost:4000 in your browser, you'll be redirected to the Blocks platform with your locally-developed blocks embedded in it. You can see your blocks by clicking on the block picker toward the top of the page (they're shown at the top in blue with a plug icon):
This starter project has one example folder block and one example file block. Try choosing one of the example blocks in the block picker to see it in action. When you make changes to the block code it will be hot-reloaded in the app.
If you don't see your blocks, make sure that:
- your development server is running
- there's a
devServerquery parameter in the URL pointing to your development server, like this - if you're using Safari (or another browser that doesn't permit calling
httpURLs from anhttpspage), runyarn start-httpsand visit https://localhost:4000 instead
To create your own custom blocks you need to do two things:
- Define your custom block
- Code your block
If you open up /blocks.config.json, you'll notice an array of block objects with the definitions for each custom block. Block objects follow this interface:
interface BlockDefinition {
type: "file" | "folder";
id: string;
title: string;
description: string;
entry: string;
matches?: string[];
}You have to define these properties for your own custom block.
From top to bottom:
typedetermines whether this block applies to files or folders.idis an identifier string for this block, like"code-block". GitHub Blocks uses this to determine which block to render; it needs to be unique within your project.titleanddescriptioncontrol how your block appears within the GitHub Blocks application.entryis the path (relative to the project root) to the block's entry point, like"blocks/example-file-block/index.tsx".matchesis an array of globs describing filenames for which GitHub Blocks should show this block as an option, like["*.json"]for a block that handles JSON files, or["*"]for one that handles any file. (The glob syntax follows github.com/micromatch/picomatch)
🚨 Note that the
/blocks.config.jsonfile is not hot-reloaded, so you'll need to pick-up the changes by either refreshing the app or clicking the "refresh" button in the block picker.
Your code goes in the blocks/ directory. Here you'll find the two example blocks as a starting point. You can modify them, rename them (don't forget to update blocks.config.json if you change the path or file names), or just delete them.
Note that your Block entry file must have the Block component as its default export so the GitHub Blocks application can find it.
Blocks can store freeform metadata about themselves in the repository where they are used (as opposed to the repo containing the code that powers the block). Metadata is unique per file/folder per Block, and committed to the .github/blocks/ folder.
Often, metadata is used to store configuration data, so that you can customize how a block works by default for a specific file or folder in your repository.
To store or update metadata, call the onUpdateMetadata hook which is supplied to your block as a prop. The user will be prompted to accept the change and commit the new metadata to the repository.
When you next view the specific content with that block, the metadata prop will contain the committed metadata.
Blocks are not just for viewing content! They can also offer custom interfaces for editing content.
There are three props which facilitate editing content in blocks:
originalContent: contains the original contents of the file. This is useful if you want to be able to display a diff of changes made, but not yet committed.isEditable: a flag indicating whether the current user has permission to edit the file. If it is false, the block should disable editing functionality, if present.onUpdateContent: a hook that can be called to update content programmatically. Users can also commit changes using theSavebutton in the Blocks interface next to the block picker. Whether triggered via the hook or the save button, the Blocks platform will display a dialog containing a diff to the user, and ask for their permission to make a commit. Commits are recorded as being authored by the user that made (and approved) the request.
Blocks can be nested inside other blocks using BlockComponent; you can retrieve a list of available blocks using onRequestBlocksRepos. See the edit-and-preview block for an example of their use.
Import other files? You can import CSS files or split your block into multiple TypeScript files, and everything will be bundled with your block.
Use third-party dependencies?
You can use any third-party dependencies from NPM; just add them with yarn add and import them as usual, and they'll be bundled with your block.
Style my block like GitHub? The GitHub Primer React components are already included as a dependency
If you're looking for examples or inspiration, check out our repo full of example blocks.


