Introduced in 2020, the GitHub user profile README allow individuals to give a long-form introduction. This multi-part tutorial explains how I setup my own profile to create dynamic content to aid discovery of my projects:
- with the Liquid template engine and Shields (keep reading below)
- using GitHub's GraphQL API to query dynamic data about all my repos (Part 2 of 4)
- fetching RSS and Social cards from third-party sites (Part 3 of 4)
- automating updates with GitHub Actions (Part 4 of 4)
You can visit github.com/j12y to see the final result of what I came up with for my own profile page.
Getting Started with Profile README
A profile on GitHub consists of standard attributes like profile name, picture, location, bio and status. Also included on a profile page are dynamic elements such as pinned repositories, stars, followers, contribution graph and activity feed.
The GitHub profile README file adds the capability to provide additional flair and free-form content. It is a specific file and repository that will render on your profile by following the proper conventions.
To get your profile to hello world
you need to follow a few steps:
- Create a repository named identical to your username. So for example, my repos name is "j12y" because my GitHub login is "j12y". If your login is "octocato" then the repository would be named "octocato".
- Create a file README.md in the repository.
- Put any markdown or HTML you'd like such as
# Hello World
in the file and commit it to themain
branch.
This is the convention for individuals. For organizations, the repo is called .github and the file profile/README.md.
The result is rendered on your profile page like so:
Generally, anything that is in the README.md is what will be rendered to your profile much like it would be in the README.md within an individual repository.
I stumbled upon a list of awesome GitHub Profile READMEs and spent quite some time reviewing them for inspiration. There are some very creative folks out there that have found interesting ways to express themselves and their projects. Those and other resources go into more examples of the things you can do:
- putting in banner images
- collapsible sections for details
- changing fonts
- making tables
- etc.
Check those resources out for some basic formatting tutorials.
Generating a README from a Template
To support the idea I had in mind for my own profile README I wanted to use a template engine. That is, I wanted to be able to fetch dynamic data and then substitute it into a template that generates the final README.md as the output.
┌────────────┐ ┌─────────────┐
│ │ │ │
│ template.a ├────────────► README.md │
│ │ │ │
└───┬────────┘ └─────────────┘
│
│ ┌────────────┐
│ │ │
├──┤ template.b │ <----- DATA
│ │ │
│ └────────────┘
│
│ ┌────────────┐
│ │ │
│ │ template.c │
└──┤ │
└────────────┘
I spent some time researching options:
- handlebars
- mustache
- pug
- smarty
- liquid
- etc.
I had used handlebars and mustache on web projects in the past and evaluated pug which was new to me and had never used before just for the sake of learning more about it. I planned this project to be a node
script using TypeScript
for reasons. Finding an easy to use example of Liquid + TypeScript that worked out of the box was the primary deciding factor in choosing it given I only have a few basic requirements.
Initializing the TypeScript Project
I initialized my TypeScript project:
npm init -y
npm install --save-dev typescript
npx tsc --init --rootDir src --outDir build
npm install -D @types/node
npm install -D ts-node
and configured tsconfig.json and package.json to run my build with npm start
by executing:
ts-node ./src/app.ts
Getting Started with a Simple Liquid Template
The source directory project is minimimalistic boilerplate and structured like this:
├── package-lock.json
├── package.json
├── src
│ ├── app.ts
│ └── template
│ ├── README.liquid
│ └── contact.liquid
└── tsconfig.json
When src/app.ts is executed, it resolves the paths of the templates in order to generate the output README.md from the entry point of the README.liquid template.
// src/app.js
import path from 'path'
import { Liquid } from 'liquidjs'
import { writeFileSync } from 'fs'
export async function main() {
let scope = {};
const engine = new Liquid({
root: path.resolve(__dirname, 'template/'),
extname: '.liquid'
});
engine.renderFile('README', scope).then((content) => {
writeFileSync(path.join(__dirname, '../README.md'), content, {flag: 'w'});
});
}
main();
The liquid template contains any markdown or html that should appear in the final README.md that will be generated into the root of the project.
<!-- src/template/README.liquid -->
# Hello World
Using Shields for Visual Flair
If you've spent time on GitHub exploring repositories you've likely encountered shields. These status boxes can be either static or dynamic but provide a nice visual callout to things like build status, code coverage, downloads, follower counts, etc.
They can also serve as a helpful visualization for social links. The docs explain that any logo provided in simple-icons can be used.
So defining what you want can be used to construct a URL:
- Label: LinkedIn
- Message: none
- Logo: linkedin
- logoColor: #0077B5
Putting this together, the main entry point to the templates is src/template/README.liquid:
<!-- src/template/README.liquid -->
{% include 'contact' %}
This includes a second template to store all of the contact information such as social profiles in src/template/contact.liquid:
<!-- src/template/contact.liquid -->
# Hello World
<div id="social" align="center">
<a href="https://www.linkedin.com/in/jaysondelancey/" target="_blank"><img src="https://img.shields.io/badge/LinkedIn-0077B5?style=flat-square&logo=linkedin&logoColor=white" alt="@jaysondelancey on LinkedIn"/></a>
</div>
Now we have badges that can be used for a bit more pop than HTML text anchors.
Learn More About GitHub Readme Profiles
As you let this introduction to setup of a GitHub Profile Readme marinate, the next articles will dive into some of the more interesting applications of GitHub features.
- Creating a topic explorer for repos using GraphQL (Part 2 of 4)
- Fetching RSS and Social Cards for GitHub Profile (Part 3 of 4)
- Automating GitHub Profile Updates with Actions (Part 4 of 4)
Did this help you get your own profile started? Let me know and follow to get notified about updates.
Top comments (0)