Skip to content

stefanBid/sb-template-nuxt

Repository files navigation

SB-Template Nuxt Logo

SB-Template Nuxt

πŸš€ Production-Ready Nuxt 3 Starter with Superpowers

Node.js Vue Nuxt TypeScript Tailwind CSS i18n ESLint

Stop wasting time on boilerplate. Start building features.

A battle-tested, feature-rich Nuxt 3 template that includes everything you need: modern design system, reusable UI components, i18n support, and CI/CD ready to deploy. Build beautiful, production-ready interfaces in minutes, not weeks.

Quick Start β€’ Features β€’ Components β€’ Deploy


πŸ“‹ Table of Contents


✨ Core Features

🎨 Styling & Design System

  • Tailwind CSS 4.1.18 - Modern utility-first CSS with custom design tokens
  • Custom Theme System - Pre-configured theme with CSS variables for easy customization
  • Typography Utilities - 9 ready-to-use text styles (ty-app-hero, ty-app-title, etc.)
  • Color Palette - Semantic color system (main, surface, accent, contrast, muted, error)
  • Responsive Design - Mobile-first with smooth transitions on all breakpoints
  • Dark Mode Ready - Theme structure prepared for dark mode implementation

🌍 Internationalization (i18n)

  • @nuxtjs/i18n 10.2.1 - Complete i18n solution
  • English & Italian included (easily add more)
  • URL Strategy - prefix_except_default (e.g., /page for EN, /it/page for IT)
  • Translation Files - JSON-based translations in i18n/locales/

🧩 Pre-Built Components

  • TheHeader - Responsive navigation with mobile drawer
  • TheFooter - Multi-column footer with social links
  • TheNotificationBanner - Toast notifications (success, error, warning, info)
  • BaseIconMenu - Floating dropdown menu with keyboard navigation
  • BaseCloseButton - Accessible close button

🧩 Ready-to-Use Components

Build modern interfaces in minutes. This template includes a complete library of production-ready, accessible, and fully customizable UI components designed to accelerate your development workflow.

🎨 Form Components

BaseButton

Full-featured button component with multiple variants and states.

Variants: primary, secondary, outline Types: button, submit, reset, link States: loading, disabled Features: Icon support, accessible, keyboard navigation

<BaseButton variant="primary" :is-loading="false">
  <Icon name="lucide:send" class="size-5 mr-2" />
  Send Message
</BaseButton>

<BaseButton variant="outline" type="link" to="/about">
  Learn More
</BaseButton>

BaseInput

Text input with label, hints, error states, and prefix icons.

Types: text, email, password, number Features: Validation states, accessible, auto-focus, prefix icons

<BaseInput
  id="email"
  v-model:input="email"
  type="email"
  label="Email Address"
  placeholder="user@example.com"
  prefix-icon="lucide:mail"
  hint="We'll never share your email"
  :error="emailError"
/>

BaseTextarea

Multi-line text input with character counter.

Features: Character limit, auto-resize, validation states

<BaseTextarea
  id="message"
  v-model:input="message"
  label="Your Message"
  :max-length="500"
  :rows="4"
  placeholder="Type your message..."
/>

BaseCheckbox

Custom checkbox with label slot.

Features: Custom styling, accessible, label slot

<BaseCheckbox id="terms" v-model:input="acceptTerms">
  I agree to the terms and conditions
</BaseCheckbox>

BaseCombobox

Advanced select component with single/multiple selection.

Types: single, multiple Features: Searchable, keyboard navigation, floating UI, custom icons

<BaseCombobox
  id="country"
  v-model:input="selectedCountries"
  type="multiple"
  :items="countries"
  label="Select Countries"
  prefix-icon="lucide:globe"
  placeholder="Choose countries..."
/>

BaseChip

Compact label component for tags, badges, and status indicators.

Variants: accent, primary, secondary Features: Icon support, rounded design, responsive sizing

<!-- Simple chip -->
<BaseChip text="Featured" variant="accent" />

<!-- Chip with icon -->
<BaseChip
  icon="lucide:star"
  text="Premium"
  variant="accent"
/>

<!-- Use cases -->
<BaseChip icon="lucide:code" text="Vue.js" variant="accent" />
<BaseChip icon="lucide:check-circle" text="Active" variant="accent" />
<BaseChip icon="lucide:folder" text="Design" variant="primary" />

πŸ“¦ Layout Components

BaseCard

Flexible card container with slots for header, body, and footer.

Variants: dark, light, dark-hover, light-hover Alignment: left, center, right Slots: card-header, card-body, card-footer, default

<BaseCard
  title="Card Title"
  subtitle="Card Subtitle"
  paragraph="Card description text"
  variant="dark-hover"
  align="center"
>
  <template #card-header>
    <Icon name="lucide:star" class="size-6 text-app-accent" />
  </template>

  <template #card-footer>
    <BaseButton variant="primary">Action</BaseButton>
  </template>
</BaseCard>

<!-- Full custom content -->
<BaseCard :full-custom-content="true">
  <div class="custom-layout">
    <!-- Your custom content -->
  </div>
</BaseCard>

BaseDialog

Modal dialog with size variants and custom slots.

Sizes: sm, md, lg, full Features: Scroll lock, keyboard (ESC), accessible, click outside to close

<BaseDialog
  :is-open="isDialogOpen"
  size="md"
  title="Dialog Title"
  subtitle="Dialog subtitle"
  @close="isDialogOpen = false"
>
  <template #header>
    <div class="custom-header">
      <!-- Optional custom header content -->
    </div>
  </template>

  <p>Dialog content goes here</p>

  <template #footer>
    <BaseButton variant="outline" @click="isDialogOpen = false">
      Cancel
    </BaseButton>
    <BaseButton variant="primary" @click="handleSave">
      Save
    </BaseButton>
  </template>
</BaseDialog>

🧭 Navigation Components

BaseIconMenu

Dropdown menu with floating UI and keyboard navigation.

Features: Floating positioning, keyboard support, click outside to close

<BaseIconMenu
  icon="lucide:menu"
  :items="menuItems"
  :selected-item-id="selectedId"
  @select="handleSelect"
/>

<script setup>
const menuItems = [
  { code: 'profile', label: 'Profile', icon: 'lucide:user', iconType: 'nuxt-icon' },
  { code: 'settings', label: 'Settings', icon: 'lucide:settings', iconType: 'nuxt-icon' },
]
</script>

πŸ”” Feedback Components

TheNotificationBanner

Toast notification system with multiple types.

Types: success, error, warning, info Features: Auto-dismiss, manual close, stacking

<script setup>
const { notify } = useAppNotifications()

notify({
  type: 'success',
  title: 'Success!',
  description: 'Your changes have been saved.',
  duration: 5000,
})
</script>

🎯 Why These Components?

βœ… Accessible - ARIA attributes, keyboard navigation, focus management βœ… Responsive - Mobile-first design with smooth transitions βœ… Customizable - Full theme support with CSS variables βœ… Type-Safe - Complete TypeScript support βœ… Production-Ready - Battle-tested in real projects βœ… i18n Ready - Internationalization support built-in

See all components in action: Run npm run dev and visit the homepage for a complete showcase.

πŸ› οΈ Developer Experience

  • TypeScript - Full type safety
  • ESLint 9.39.1 - Code quality with stylistic rules
  • VueUse 14.1.0 - Vue composition utilities
  • Floating UI 1.1.9 - Tooltips, popovers, dropdowns
  • Auto-imports - Components and composables automatically imported
  • Hot Module Replacement - Lightning-fast development

πŸ–ΌοΈ Asset Optimization

  • @nuxt/image 2.0.0 - Automatic image optimization
  • Multiple Formats - WebP, AVIF, PNG support
  • Responsive Images - Automatic srcset generation
  • Cloudinary Ready - Pre-configured provider
  • @nuxt/icon 2.1.0 - SVG icon system with Lucide icon collection
  • Icon Library - 1000+ Lucide icons ready to use

βš™οΈ CI/CD Ready

  • GitHub Actions - Pre-configured workflows
  • Automated Testing - Lint and build checks on PR
  • Release Please - Automated versioning and changelog
  • Netlify Preset - Optimized for Netlify deployment (easily switch to Vercel, Cloudflare, etc.)

πŸš€ Quick Start

Prerequisites

  • Node.js β‰₯ 24.11.0
  • npm / pnpm / yarn

Installation

Option 1: Use as GitHub Template (Recommended)

  1. Click "Use this template" on GitHub
  2. Clone your new repository:
git clone https://github.com/your-username/your-project.git
cd your-project

Option 2: Clone Directly

git clone https://github.com/stefanoBid/sb-nuxt-template.git my-project
cd my-project
rm -rf .git && git init  # Start fresh

Setup

# Install dependencies
npm install

# (Optional) Reset version to 0.1.0
echo "# Changelog" > CHANGELOG.md
npm version 0.1.0 --no-git-tag-version

# Start development server
npm run dev

Visit http://localhost:3000 πŸŽ‰


πŸ“ Project Structure

sb-template-nuxt/
β”œβ”€β”€ app/
β”‚   β”œβ”€β”€ assets/
β”‚   β”‚   └── css/
β”‚   β”‚       β”œβ”€β”€ main.css          # Main CSS entry point
β”‚   β”‚       β”œβ”€β”€ theme.css         # CSS variables & design tokens
β”‚   β”‚       β”œβ”€β”€ typography.css    # Typography utilities (ty-app-*)
β”‚   β”‚       β”œβ”€β”€ animations.css    # Animation classes
β”‚   β”‚       └── utilities.css     # Custom utility classes
β”‚   β”‚
β”‚   β”œβ”€β”€ components/
β”‚   β”‚   β”œβ”€β”€ base/
β”‚   β”‚   β”‚   β”œβ”€β”€ button/           # BaseButton.vue - Multi-variant button
β”‚   β”‚   β”‚   β”œβ”€β”€ card/             # BaseCard.vue - Flexible card container
β”‚   β”‚   β”‚   β”œβ”€β”€ checkbox/         # BaseCheckbox.vue - Custom checkbox
β”‚   β”‚   β”‚   β”œβ”€β”€ chip/             # BaseChip.vue - Tag/badge component
β”‚   β”‚   β”‚   β”œβ”€β”€ close-button/     # BaseCloseButton.vue - Accessible close button
β”‚   β”‚   β”‚   β”œβ”€β”€ combobox/         # BaseCombobox.vue - Select dropdown
β”‚   β”‚   β”‚   β”œβ”€β”€ dialog/           # BaseDialog.vue - Modal dialog
β”‚   β”‚   β”‚   β”œβ”€β”€ icon-menu/        # BaseIconMenu.vue - Dropdown menu
β”‚   β”‚   β”‚   β”œβ”€β”€ input/            # BaseInput.vue - Text input with validation
β”‚   β”‚   β”‚   └── textarea/         # BaseTextarea.vue - Multi-line input
β”‚   β”‚   β”œβ”€β”€ the-footer/           # TheFooter.vue
β”‚   β”‚   β”œβ”€β”€ the-header/           # TheHeader.vue & TheHeaderMenuToggle.vue
β”‚   β”‚   └── the-notification/     # TheNotificationBanner.vue & Box
β”‚   β”‚
β”‚   β”œβ”€β”€ composables/
β”‚   β”‚   β”œβ”€β”€ useAppNotifications.ts  # Notification system
β”‚   β”‚   β”œβ”€β”€ useFloatingUi.ts        # Floating UI helper
β”‚   β”‚   β”œβ”€β”€ useLockScroll.ts        # Scroll lock utility
β”‚   β”‚   └── useSanitize.ts          # HTML sanitization
β”‚   β”‚
β”‚   β”œβ”€β”€ layouts/
β”‚   β”‚   └── default.vue             # Default page layout
β”‚   β”‚
β”‚   β”œβ”€β”€ pages/
β”‚   β”‚   └── index.vue               # Homepage
β”‚   β”‚
β”‚   β”œβ”€β”€ plugins/
β”‚   β”‚   └── scrollToTop.client.ts   # Auto-scroll on route change
β”‚   β”‚
β”‚   β”œβ”€β”€ types/
β”‚   β”‚   └── global.d.ts             # Global TypeScript types
β”‚   β”‚
β”‚   β”œβ”€β”€ utils/
β”‚   β”‚   └── generateUuid.ts         # UUID generator
β”‚   β”‚
β”‚   β”œβ”€β”€ app.vue                      # Root component
β”‚   └── error.vue                    # Error page
β”‚
β”œβ”€β”€ i18n/
β”‚   └── locales/
β”‚       β”œβ”€β”€ en.json                  # English translations
β”‚       └── it.json                  # Italian translations
β”‚
β”œβ”€β”€ public/
β”‚   β”œβ”€β”€ favicon.ico
β”‚   β”œβ”€β”€ robots.txt
β”‚   └── sitemap.xml                  # SEO sitemap template
β”‚
β”œβ”€β”€ nuxt.config.ts                   # Nuxt configuration
β”œβ”€β”€ tsconfig.json                    # TypeScript configuration
β”œβ”€β”€ eslint.config.mjs                # ESLint configuration
└── package.json

πŸ› οΈ Available Scripts

Command Description
npm run dev Start development server at http://localhost:3000
npm run build Build for production (outputs to .output/)
npm run generate Generate static site (SSG mode)
npm run preview Preview production build locally
npm run lint Check code quality with ESLint
npm run lint:fix Auto-fix ESLint issues

🎨 Customization

🎨 Theme & Styling

Customize Design Tokens

Edit app/assets/css/theme.css to change colors, fonts, and spacing:

@theme {
  /* Fonts */
  --font-app-primary: 'Your Font', system-ui, sans-serif;
  --font-app-secondary: 'Your Mono Font', monospace;

  /* Colors */
  --color-app-main: #f8f9fa;        /* Background */
  --color-app-accent: #2563eb;      /* Primary accent */
  --color-app-contrast: #1a1a1a;    /* Text color */
  --color-app-error: #dc2626;       /* Error state */
  /* ...more colors */
}

πŸ’‘ Tip: All CSS variables are prefixed with app- to avoid conflicts.

Typography Utilities

Pre-configured typography classes in app/assets/css/typography.css:

Class Usage Example
ty-app-hero Hero text (60px) Landing page headlines
ty-app-title-xl Extra large title (48px) Page titles
ty-app-title-lg Large title (36px) Section headers
ty-app-title Regular title (24px) Card headers
ty-app-subtitle-lg Large subtitle (20px) Subheadings
ty-app-subtitle Regular subtitle (18px) Small subheadings
ty-app-paragraph Body text (16px) Paragraph content
ty-app-label Small label (14px) Form labels, captions
ty-app-btn-label Button text (16px) Button labels

Example:

<template>
  <h1 class="ty-app-hero">Welcome to My App</h1>
  <p class="ty-app-paragraph">This is a paragraph with proper styling.</p>
</template>

Custom Animations

Use pre-defined animation classes from app/assets/css/animations.css:

  • fade-in / fade-out
  • slide-in-up / slide-in-down
  • bounce-in

🌍 Internationalization

Add a New Language

1. Register the locale in nuxt.config.ts:

i18n: {
  locales: [
    { code: 'en', iso: 'en-US', name: 'English', file: 'en.json' },
    { code: 'it', iso: 'it-IT', name: 'Italiano', file: 'it.json' },
    { code: 'fr', iso: 'fr-FR', name: 'FranΓ§ais', file: 'fr.json' }, // βœ… New
  ],
}

2. Create translation file i18n/locales/fr.json:

{
  "welcome": "Bienvenue",
  "nav": {
    "home": "Accueil",
    "about": "Γ€ propos"
  }
}

3. Use translations in components:

<template>
  <h1>{{ $t('welcome') }}</h1>
  <NuxtLink :to="localePath('/')">{{ $t('nav.home') }}</NuxtLink>
</template>

Switch Languages Programmatically

<script setup>
const { locale, setLocale } = useI18n()

function changeLanguage(lang: string) {
  setLocale(lang)
}
</script>

<template>
  <button @click="changeLanguage('it')">Italiano</button>
  <button @click="changeLanguage('en')">English</button>
</template>

🧩 Using Built-in Components

Notification System

<script setup>
const { notify } = useAppNotifications()

function showSuccess() {
  notify({
    type: 'success',
    title: 'Success!',
    description: 'Your action was completed.',
    duration: 5000, // Auto-dismiss after 5s
  })
}

function showError() {
  notify({
    type: 'error',
    title: 'Error!',
    description: 'Something went wrong.',
    duration: 0, // Manual dismiss only
  })
}
</script>

<template>
  <button @click="showSuccess">Show Success</button>
  <button @click="showError">Show Error</button>
</template>

Notification Types: success, error, warning, info

Icon Menu (Dropdown)

<template>
  <BaseIconMenu>
    <template #trigger="{ toggle }">
      <button @click="toggle">
        <Icon name="mdi:menu" />
      </button>
    </template>

    <template #content>
      <div class="p-4 bg-white rounded-lg shadow-lg">
        <a href="/profile">Profile</a>
        <a href="/settings">Settings</a>
        <button @click="logout">Logout</button>
      </div>
    </template>
  </BaseIconMenu>
</template>

πŸ”§ Composables Reference

useAppNotifications()

Manage toast notifications.

const { notify, removeNotification, notifications } = useAppNotifications()

// Show notification
notify({
  type: 'success',
  title: 'Title',
  description: 'Description',
  duration: 5000, // ms (0 = manual dismiss)
})

// Remove specific notification
removeNotification(id)

useFloatingUi(reference, floating, options)

Position floating elements (tooltips, dropdowns).

const reference = ref<HTMLElement>()
const floating = ref<HTMLElement>()

const { floatingStyles } = useFloatingUi(reference, floating, {
  placement: 'bottom-start',
  offset: 8,
})

useLockScroll()

Lock/unlock body scroll (useful for modals).

const { lockScroll, unlockScroll } = useLockScroll()

// Lock scroll when modal opens
onMounted(() => lockScroll())

// Unlock when modal closes
onUnmounted(() => unlockScroll())

useSanitize(html)

Sanitize HTML to prevent XSS attacks.

const { sanitizeHtml } = useSanitize()

const cleanHtml = sanitizeHtml('<script>alert("xss")</script><p>Safe content</p>')
// Result: '<p>Safe content</p>'

πŸ–ΌοΈ Image Optimization

Using Nuxt Image

<template>
  <!-- Local images (from public/) -->
  <NuxtImg
    src="/images/hero.jpg"
    alt="Hero image"
    width="800"
    height="600"
    format="webp"
    loading="lazy"
  />

  <!-- Cloudinary images -->
  <NuxtImg
    provider="cloudinary"
    src="/sample.jpg"
    alt="Sample"
    width="400"
    height="300"
  />

  <!-- External images (requires domain whitelisting) -->
  <NuxtImg
    src="https://example.com/image.jpg"
    alt="External"
    width="600"
    height="400"
  />
</template>

Configure external domains in nuxt.config.ts:

image: {
  domains: [
    'https://api.example.com',
    'https://cdn.yoursite.com',
  ],
}

Icons

<template>
  <!-- MDI icons -->
  <Icon name="mdi:home" size="24" />
  <Icon name="mdi:account-circle" size="32" color="blue" />

  <!-- Flag icons -->
  <Icon name="flagpack:it" size="24" />
  <Icon name="flagpack:us" size="24" />
</template>

Browse available icons:


βš™οΈ Environment Variables

Create a .env file in the project root:

# API Configuration
NUXT_PUBLIC_API_URL=https://api.yoursite.com

# Cloudinary
NUXT_PUBLIC_CLOUDINARY_BASE=https://res.cloudinary.com/your-cloud-name

# CMS (Strapi, etc.)
NUXT_PUBLIC_STRAPI_URL=https://cms.yoursite.com

# Analytics
NUXT_PUBLIC_GA_ID=G-XXXXXXXXXX

Access in your app:

const config = useRuntimeConfig()
const apiUrl = config.public.apiUrl

⚠️ Important: Only variables prefixed with NUXT_PUBLIC_ are exposed to the client.


πŸ“¦ Deployment

Netlify (Default Configuration)

This template is pre-configured for Netlify deployment.

1. Build your app:

npm run build

2. Deploy to Netlify:

  • Connect your GitHub repository to Netlify
  • Build command: npm run build
  • Publish directory: .output/public

3. Environment variables: Add your .env variables in Netlify dashboard under Site settings β†’ Environment variables.


Vercel

1. Change preset in nuxt.config.ts:

nitro: {
  preset: 'vercel',
}

2. Deploy:

npm run build
vercel deploy

Cloudflare Pages

1. Change preset:

nitro: {
  preset: 'cloudflare-pages',
}

2. Build and deploy:

npm run build
# Deploy .output/public to Cloudflare Pages

Node.js Server

1. Change preset:

nitro: {
  preset: 'node-server',
}

2. Build and run:

npm run build
node .output/server/index.mjs

πŸ“š More deployment options: Nuxt Deployment Docs


πŸ”„ CI/CD Workflows

This template includes GitHub Actions workflows for automated testing and releasing.

Continuous Integration (CI)

Triggers:

  • Push to main, develop, release/** branches
  • Pull requests to main

Actions:

  1. βœ… Checkout code
  2. βœ… Install dependencies (npm ci)
  3. βœ… Run linter (npm run lint)
  4. βœ… Build app (npm run build)

Smart Skip: The workflow automatically skips heavy steps for Release Please PRs (only marks as passed).

Workflow file: .github/workflows/ci.yml


Automated Versioning (Release Please)

Trigger: Push to main branch

What it does:

  1. Analyzes conventional commits (e.g., feat:, fix:, chore:)
  2. Creates/updates a Release PR with:
    • Auto-generated changelog
    • Version bump in package.json
  3. When merged, creates a GitHub Release with tags

Commit Message Format:

# Features
git commit -m "feat: add dark mode support"

# Bug fixes
git commit -m "fix: resolve navigation issue on mobile"

# Breaking changes
git commit -m "feat!: redesign authentication system"

# Chores (no release)
git commit -m "chore: update dependencies"

πŸ’‘ Tip: Use conventional commits to automate versioning!

Workflow file: .github/workflows/release-please.yml


Starting Fresh

If you want your project to start from version 0.1.0 instead of inheriting the template's version:

# Clear changelog
echo "# Changelog" > CHANGELOG.md

# Reset version
npm version 0.1.0 --no-git-tag-version

# Commit changes
git add .
git commit -m "chore: initialize project from template"

πŸ§ͺ What You Can Build

This template is perfect for:

βœ… Landing Pages - Fast, SEO-optimized, multi-language βœ… Marketing Sites - With optimized images and analytics ready βœ… Documentation Sites - Custom styling and navigation βœ… SaaS Applications - Notification system and user dashboards βœ… Portfolio Websites - Dynamic routing and image galleries βœ… E-commerce Stores - Product pages with i18n support


πŸ’‘ Best Practices

File Organization

  • Components: Use PascalCase for component filenames
  • Composables: Prefix with use (e.g., useAuth.ts)
  • Utils: Pure functions in app/utils/
  • Types: Global types in app/types/global.d.ts

Code Style

  • Follow ESLint rules (run npm run lint:fix before committing)
  • Use TypeScript for type safety
  • Prefer composition API over options API
  • Use auto-imports instead of manual imports

Performance

  • Lazy load components with <ClientOnly> when not needed for SSR
  • Use <NuxtImg> instead of <img> for automatic optimization
  • Prerender static pages in nuxt.config.ts β†’ routeRules
  • Keep bundle size small (check with npm run build -- --analyze)

πŸ› Troubleshooting

Common Issues

Issue: Cannot find module 'isomorphic-dompurify' Solution: This is expected during server builds. The module is excluded in nuxt.config.ts β†’ nitro.externals.

Issue: Icons not showing Solution: Make sure icon collections are installed: npm i @iconify-json/mdi @iconify-json/flagpack

Issue: i18n routes not working Solution: Check nuxt.config.ts β†’ i18n.strategy and ensure locale files exist in i18n/locales/

Issue: Images not loading from external domains Solution: Add domain to nuxt.config.ts β†’ image.domains


🀝 Contributing

Contributions are welcome! Here's how you can help:

  1. Report bugs - Open an issue with details
  2. Suggest features - Share your ideas
  3. Submit PRs - Fork, create a branch, and submit a pull request

Development Setup:

git clone https://github.com/stefanoBid/sb-nuxt-template.git
cd sb-nuxt-template
npm install
npm run dev

πŸ“„ License

This project is open source and available under the MIT License.

Feel free to use it for personal or commercial projects.


πŸ‘€ Author

Stefano Biddau

πŸ“§ Email: biddau.stefano99@gmail.com

πŸ™ GitHub: @stefanoBid

🌐 Website: stefanobiddau.com


🎨 More Templates

Looking for more starter templates? Check out the SB Templates Project collection!

πŸ‘‰ Browse All Templates

Visit the website and navigate to the SB TEMPLATES PROJECT section to discover more production-ready templates for different frameworks and use cases.


🌟 Show Your Support

If this template helped you build faster, give it a ⭐️ on GitHub!

Your support motivates me to maintain and improve this project.


πŸ“š Resources


Happy coding! πŸš€

Built with ❀️ by developers, for developers.