Nextjs - Setup with Bootstrap

Setup nextjs with bootstrap Initialize nextjs project with typescript pnpm create next-app --typescript Install bootstrap pnpm add bootstrap Add bootstrap css to app/layout.tsx or pages/_app import "bootstrap/dist/css/bootstrap.min.css"; Create a bootstrap client component components/Bootstrap.tsx "use client"; import { useEffect } from "react"; function BootstrapClient() { useEffect(() => { require("bootstrap/dist/js/bootstrap.bundle.min.js"); }, []); return null; } export default BootstrapClient; Add bootstrap client component to app/layout.tsx or pages/_app layout.tsx might look like this. import BootstrapClient from "@/components/boostrap"; import "bootstrap/dist/css/bootstrap.css"; import type { Metadata } from "next"; export const metadata: Metadata = { title: "Create Next App", description: "Generated by create next app", }; export default function RootLayout({ children, }: Readonly<{ children: React.ReactNode; }>) { return ( <html lang="en"> <body>{children}</body> <BootstrapClient /> </html> ); } Exporting as static site. Add the following to next.config.js ...

Go - Template

Let’s check the Go template syntax and essentials. Placeholders The {{ }} is used to denote a placeholder. It can contain a variable, function, control statments like if, for, range etc. a variant of placeholder is {{- -}} which is used to trim the whitespace before the placeholder, {{- trims the whitespace before the placeholder and -}} trims the whitespace after the placeholder. Variables Variables are defined using the {{ $variableName := value }} syntax. The variable can be used in the template using {{ $variableName }}. ...

Go - Options Pattern

In go, it’s really useful pattern to pass options to functions. It’s a common usecase to have optional arguments to a function. I use it mostly to initialize something with default values and optionally override them. Primary idea is to use variadic arguments to pass options to a function. eg: func NewService(options ...ServiceOption) *Service { ... } options ...ServiceOption is the variadic argument. There are two ways to do this. Using a struct with all the options as a field. Using functions with each option value as an argument. Using a struct to pass options Example usage package main type ServiceConfig struct { Color string Size int Type string } func main() { // Initialize with default values s := NewService() // Override some of the default values s = NewService(&ServiceConfig{ Color: "red", Size: 10, }) } How to setup this options pattern You can use config... to accept any number of args in a function. Let’s create a config section with init config function. ...

Go - Setup simple gofiber server.

Gofiber is a fast lightweight web framework with simple api, inspired by expressjs. The simplicity of the api makes it easy to get started with. It’s also fast and has a lot of features. Setup Create a new project Create a new directory and initialize a go module. go mod init github.com/adharshmk96/gofiber-init Install gofiber go get -u github.com/gofiber/fiber/v2 a main.go with hello world touch main.go package main import "github.com/gofiber/fiber/v2" func main() { // gofiber with default settings app := fiber.New() // handler for root path app.Get("/", func(c *fiber.Ctx) error { return c.SendString("Hello, World 👋!") }) // start server on port 3000 app.Listen(":3000") fmt.Println("Server started on port 3000") } Dockerfile for building the app ...

Benchmarking JSON vs HTML processing functions

This benchmark compares performance of JSON serialization and HTML template rendering. In a server returning HTML or JSON the main difference is with the serialization. So I wanted to know how much difference it makes to return a JSON response vs HTML response. So I just tested json serialization vs html template rendering in Go. Benchmarking Setup The setup is simple, with go test, main_test.go package main import ( "bytes" "encoding/json" "testing" "text/template" "github.com/flosch/pongo2/v6" ) // Example struct to marshal type SimpleStruct struct { Field1 string `json:"field1"` Field2 int `json:"field2"` } // BenchmarkJsonMarshalling tests the performance of JSON marshaling. func BenchmarkJsonMarshalling(b *testing.B) { // setup any necessary data for the benchmark data := SimpleStruct{ Field1: "example", Field2: 123, } // Run the benchmark for i := 0; i < b.N; i++ { _, err := json.Marshal(data) if err != nil { b.Fatal(err) } } } func BenchmarkHTMLRenderingWithPongo(b *testing.B) { tpl, err := pongo2.FromString("Hello {{ name }}!") if err != nil { panic(err) } // Run the benchmark for i := 0; i < b.N; i++ { _, err := tpl.Execute(pongo2.Context{"name": "florian"}) if err != nil { b.Fatal(err) } } } func BenchmarkHTMLRenderingWithTemplate(b *testing.B) { data := map[string]string{ "Field1": "example", } tmpl := template.Must(template.New("test").Parse("Hello {{ .Field1 }}!")) // Run the benchmark for i := 0; i < b.N; i++ { memory := new(bytes.Buffer) err := tmpl.Execute(memory, data) if err != nil { b.Fatal(err) } } } Benchmarking Results BenchmarkJsonMarshalling-14 9746420 103.6 ns/op BenchmarkHTMLRenderingWithPongo-14 2557006 467.0 ns/op BenchmarkHTMLRenderingWithTemplate-14 7220666 168.7 ns/op My Thoughts JSON serialization is bit faster than HTML template rendering. ...

HTMX - Using hx-select and hx-select-oob

hx-select When the server returns a broad html response, we can use hx-select to select a part of the response and replace the target element with it. For example, consider the following html <body> <div id="main-info"> </div> <div> Some content here </div> <button hx-get="/get-update" hx-target="#main-info" hx-select="#main-info"> update </button> </body> and we get a response from /get-update endpoint like this <div id="main-info"> Main information <p>This is main info</p> </div> <div id="extra-info"> <p>Additional info 1</p> <p>Additional info 2</p> </div> The hx-select will only select the element with id main-info and replace the target element #main-info with it. so the result will be ...

Nextjs - Export as static site

Nextjs is a great framework to create multiple page react applications. It can also export the whole app as a static site. This is extremely useful if we want to avoid nodejs server and use another server like nginx to host the site, which is faster and more efficient. To export the site, we need to change the next.config.js file to include the following: const nextConfig = { distDir: "build", output: "export", }; export default nextConfig; This will export the app as a static site to build folder. The build folder will contain all the static files, which can be hosted using any static hosting solution. ...

HTMX - Using hx-swap-oob

When starting to try htmx, It felt nice that we can interact and replace one area with response. As I started to build something practical, the need for updating multiple elements on response increased. Htmx has an attribute hx-swap-oob which helps to achieve exactly this. (OOB - out of bound) For an html section like this <body> <div id="main-info"> </div> <div> Some content here </div> <div id="extra-info"> </div> <button hx-get="/get-update" hx-target="#main-info" hx-swap="outerHTML"> update </button> </body> On clicking update I want 2 elements #main-info and #extra-info to be updated. Also, in some cases #extra-info can be absent. You can achieve this in one simple step ...

HTMX - Using hx-target and hx-swap

The main attraction of HTMX is that it allows us to asynchronously swap the content of an element with server response using hx-swap and hx-target attribute with minimal effort and with less / no javascript. For an html contnet like this <html> <head> <title>HTMX - Using htmx hx-target and hx-swap attribute</title> </head> <body> <div id="content"> <p>Content will be replaced here</p> </div> <button id="btn" hx-get="/get-content" hx-target="#content" hx-swap="outerHTML">Click Me</button> </body> </html> Let’s look at the button attributes ...

Github - Open repo in web editor

Using a web browser, we can open up a vscode like ide environment with our codebase ( from repo ) and throw in some edits. Goto your repo ( in github.com ) Select the url and change github.com into github.dev You get your vscode ide opened with all your repo files listed. After making edits goto Source control tab and manage changes ( stage changes ). Enter the commit message and Click commit & push, your changes are now reflected in the repo. you can manage branches and merge request through the web ide. there are few other services which allow us to edit repo on the web ide ...