Skip to content
This repository was archived by the owner on Jan 10, 2024. It is now read-only.

Latest commit

 

History

History
119 lines (74 loc) · 6.91 KB

File metadata and controls

119 lines (74 loc) · 6.91 KB

Building your first block

Let's jump in! Use the blocks-template as your starting point so you can focus on the fun parts of block development.

Setup

✨👉 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:

"Create a new repository from blocks-template" screen

Finally, clone your newly-created repository, and you're ready to work.

Developing locally

git clone <repo URL>
cd <repo name>
yarn # install dependencies
yarn start # start the dev server

A development server should now be running on localhost:4000.

View your development server within the Blocks app

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):

Block picker

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.

Troubleshooting the dev server

If you don't see your blocks, make sure that:

  • your development server is running
  • there's a devServer query parameter in the URL pointing to your development server, like this
  • if you're using Safari (or another browser that doesn't permit calling http URLs from an https page), run yarn start-https and visit https://localhost:4000 instead

The GitHub Blocks API

To create your own custom blocks you need to do two things:

  • Define your custom block
  • Code your block

Define your custom 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:

  • type determines whether this block applies to files or folders.
  • id is 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.
  • title and description control how your block appears within the GitHub Blocks application.
  • entry is the path (relative to the project root) to the block's entry point, like "blocks/example-file-block/index.tsx".
  • matches is 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.json file 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.

Code your block

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.

Important block concepts

Metadata

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.

Updating content

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 the Save button 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.

Nesting

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.

How might I...

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.