DEV Community

Cover image for Your own github shield server in 50 loc!
myleftshoe
myleftshoe

Posted on

Your own github shield server in 50 loc!

Yes, 50 lines of code and you have your own custom shield/badge generator for your github READMEs!

And by server, I mean "serverless" - using vercel.


Prerequsites:

If you don't already have one, create a free account at vercel. Then install the Vercel CLI and log in.

npm install -g vercel
vercel login
Enter fullscreen mode Exit fullscreen mode

Create a new npm project:

mkdir mybadgeserver
cd mybadgeserver
npm init
Enter fullscreen mode Exit fullscreen mode

Create the API endpoint:

The square brackets are required!

mkdir -p api/[label]/[value]
cd api/[label]/[value] 
touch index.js
Enter fullscreen mode Exit fullscreen mode

Paste the following code into index.js

module.exports = (req, res) => {
    const { label, value, ...options } = req.query
    const svg = makeShield(label, value, options) 
    res.setHeader('content-type', 'image/svg+xml')
    res.send(svg)
}

const defaultOptions = {
    labelColor: 'orange',
    valueColor: '#777',
    fontSize: '.8rem',
}

function makeShield(label, value, options = {}) {
    label = label ?? 'label'
    value = value ?? 'value'
    options = {...defaultOptions, ...options }
    console.log({options})
    return `<svg fill="none" viewBox="0 0 300 50" width="300" height="50" xmlns="http://www.w3.org/2000/svg">
        <style>
            shield {
                position: relative;
                margin: 5px;
                display:flex;
                color: white;
                font-size: ${options.fontSize};
                font-family: 'DejaVu Sans Mono', Verdana, DejaVu Sans, sans-serif;
            }
            label {
                background-color: ${options.labelColor};
                padding: 5px 10px;
                font-weight: 900;
                border-radius: 5px 0 0 5px;
            }
            value {
                position: relative;
                background-color: ${options.valueColor};
                padding: 5px 10px;
                border-radius: 0 5px 5px 0;
                left: 2px;
            }
        </style>
        <foreignObject width="100%" height="100%">
            <shield xmlns="http://www.w3.org/1999/xhtml">
                <label>${label}</label>
                <value>${value}</value>
            </shield>
        </foreignObject>
    </svg>`
}

Enter fullscreen mode Exit fullscreen mode

And that's it! Fire-up the local dev server:

vercel dev
Enter fullscreen mode Exit fullscreen mode

Test the endpoint in your browser localhost:3000/api/label/value

address bar screenshot

  • Change label and value in the url to whatever you like!

  • Change colors by appending ?labelColor=red&valueColor=green to the url.

When you want to deploy to vercel just type:

vercel
Enter fullscreen mode Exit fullscreen mode

This will give you a different preview url each time you run it.

To deploy to production and get a nice "static" url type:

vercel --prod
Enter fullscreen mode Exit fullscreen mode

Bonus points:

You can eliminate the need for api in the url by creating a vercel.json in the project root (not in the api folder) with the following contents:

{
    "rewrites": [
        {
            "source": "/:label/:value",
            "destination": "/api/:label/:value"
        }
    ]
}
Enter fullscreen mode Exit fullscreen mode

DISCLAIMER: THIS IS GUIDE RATHER THAN A PRODUCTION READY SOLUTION - IT NEEDS TWEAKING - THE GENERATED SVGS ARE SURROUNDED BY TOO MUCH WHITE SPACE AND TEXT MAY CLIP IF TOO LONG.

Top comments (0)