Skip to content

Commit 7fbb30e

Browse files
committed
Implemented re-branding option for self-hosted users
1 parent b57cfde commit 7fbb30e

12 files changed

Lines changed: 305 additions & 24 deletions

File tree

.github/docs/app-customization.md

Lines changed: 134 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,134 @@
1+
# Customization Guide
2+
3+
If you're self-hosting Networking Toolbox, you can customize the branding for your instance with a few env vars.
4+
5+
## Overview
6+
7+
Networking Toolbox supports customization through environment variables. This allows you to:
8+
- Brand the application with your organization's name
9+
- Use a custom logo/icon
10+
- Set default themes and layouts
11+
- Maintain consistency across your organization
12+
13+
**Important:** These customizations only affect the default values. Users can still customize their personal preferences through the settings menu, and those will be stored in their browser's localStorage.
14+
15+
## Getting Started
16+
17+
Download the [`.env.example`](https://gist.githubusercontent.com/Lissy93/3c5f85dc0e2263a4706d3e136f0a076e/raw/62a00f625c920ac9e1cafe60721213e2ea233581/.env.example) to `.env` in the root of your project.
18+
19+
1. Copy `.env.example` to `.env`:
20+
```bash
21+
curl -o .env https://gist.githubusercontent.com/Lissy93/3c5f85dc0e2263a4706d3e136f0a076e/raw/62a00f625c920ac9e1cafe60721213e2ea233581/.env.example
22+
```
23+
24+
2. Edit `.env` and uncomment/modify the variables you want to customize
25+
26+
3. Restart your application to apply changes
27+
28+
## Available Customizations
29+
30+
### Site Branding
31+
32+
```bash
33+
# Customize your site name and description
34+
NTB_SITE_NAME=My Network Tools
35+
NTB_SITE_TITLE=My Network Tools
36+
NTB_SITE_DESCRIPTION=Professional networking utilities for your team
37+
```
38+
39+
### Custom Logo
40+
41+
Use a custom logo image in the navbar:
42+
43+
```bash
44+
NTB_SITE_ICON=/logo.svg
45+
```
46+
47+
Place your logo image in the `static/` directory and reference it with a leading slash. Supported formats: SVG, PNG, JPG, WebP.
48+
49+
### Default Layout
50+
51+
Set the default homepage layout:
52+
53+
```bash
54+
# Options: categories, default, minimal, carousel, bookmarks, small-icons, list, search, empty
55+
NTB_HOMEPAGE_LAYOUT=categories
56+
```
57+
58+
### Default Navbar Display
59+
60+
Control what appears in the top navigation:
61+
62+
```bash
63+
# Options: default, bookmarked, frequent, none
64+
NTB_NAVBAR_DISPLAY=default
65+
```
66+
67+
### Default Theme
68+
69+
Set the default color theme:
70+
71+
```bash
72+
# Options: dark, light, midnight, arctic, ocean, purple, cyberpunk, terminal, lightpurple, muteddark, solarized
73+
NTB_DEFAULT_THEME=dark
74+
```
75+
76+
## Example Configurations
77+
78+
### Corporate Branding Example
79+
80+
```bash
81+
NTB_SITE_NAME=Acme Corp Network Tools
82+
NTB_SITE_TITLE=Acme Corp Network Tools
83+
NTB_SITE_DESCRIPTION=Internal networking utilities for Acme Corp IT team
84+
NTB_SITE_ICON=/acme-logo.svg
85+
NTB_DEFAULT_THEME=light
86+
NTB_HOMEPAGE_LAYOUT=list
87+
```
88+
89+
### Minimalist Setup Example
90+
91+
```bash
92+
NTB_SITE_NAME=NetUtils
93+
NTB_SITE_DESCRIPTION=Simple network utilities
94+
NTB_DEFAULT_THEME=muteddark
95+
NTB_HOMEPAGE_LAYOUT=search
96+
NTB_NAVBAR_DISPLAY=none
97+
```
98+
99+
## Docker Deployment
100+
101+
When using Docker, pass environment variables with the `-e` flag or use a `.env` file:
102+
103+
```bash
104+
docker run -p 5000:5000 \
105+
-e NTB_SITE_NAME="My Network Tools" \
106+
-e NTB_DEFAULT_THEME="light" \
107+
lissy93/networking-toolbox
108+
```
109+
110+
Or with docker-compose:
111+
112+
```yaml
113+
services:
114+
networking-toolbox:
115+
image: lissy93/networking-toolbox
116+
ports:
117+
- "5000:5000"
118+
environment:
119+
- NTB_SITE_NAME=My Network Tools
120+
- NTB_DEFAULT_THEME=light
121+
- NTB_SITE_ICON=/custom-logo.svg
122+
volumes:
123+
- ./static:/app/static # For custom logo
124+
```
125+
126+
## Notes
127+
128+
- All environment variables must be prefixed with `NTB_` to be accessible
129+
- Changes require an application restart to take effect
130+
- The managed instance at [networking-toolbox.as93.net](https://networking-toolbox.as93.net) uses the default values
131+
- User preferences set through the UI take precedence over these defaults
132+
- Invalid values will fallback to the default settings
133+
134+

.github/workflows/report-tests.yml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ permissions:
1212
contents: read
1313
checks: write # For test reporting
1414
pull-requests: write # For PR comments
15+
actions: read
1516

1617
jobs:
1718
report:

src/lib/components/furniture/Header.svelte

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
<script lang="ts">
22
import { site } from '$lib/constants/site';
3+
import { SITE_ICON } from '$lib/config/customizable-settings';
34
import Icon from '$lib/components/global/Icon.svelte';
45
import GlobalSearch from '$lib/components/global/GlobalSearch.svelte';
56
import BurgerMenu from '$lib/components/furniture/BurgerMenu.svelte';
@@ -11,6 +12,8 @@
1112
1213
let globalSearchRef: GlobalSearch;
1314
let shortcutsDialogRef: ShortcutsDialog;
15+
16+
const hasCustomLogo = SITE_ICON && SITE_ICON.trim() !== '';
1417
</script>
1518

1619
<header class="header">
@@ -19,7 +22,11 @@
1922
<div class="logo">
2023
<div class="logo-icon">
2124
<a href="/" aria-label="Home">
22-
<Icon name="networking" size="lg" />
25+
{#if hasCustomLogo}
26+
<img src={SITE_ICON} alt={site.name} class="logo-image" />
27+
{:else}
28+
<Icon name="networking" size="lg" />
29+
{/if}
2330
</a>
2431
</div>
2532
<div>
@@ -72,6 +79,13 @@
7279
flex-shrink: 0; // Prevent logo from shrinking
7380
background: var(--bg-secondary);
7481
z-index: 1;
82+
83+
.logo-image {
84+
width: 2.5rem;
85+
height: 2.5rem;
86+
object-fit: contain;
87+
display: block;
88+
}
7589
}
7690
7791
.header-actions {

src/lib/components/page-specific/about/DeployingSection.svelte

Lines changed: 51 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,8 @@
1616
<code>docker run -p 8080:8080 lissy93/networking-toolbox</code>
1717
</div>
1818
<p>
19-
You can also checkout our <a href="https://github.com/Lissy93/networking-toolbox/blob/main/docker-compose.yml"
19+
You can also checkout our
20+
<a href="https://github.com/Lissy93/networking-toolbox/blob/main/docker-compose.yml"
2021
><code>docker-compose.yml</code></a
2122
>, using the
2223
<a href="https://hub.docker.com/r/lissy93/networking-toolbox"><code>lissy93/networking-toolbox</code></a> image from
@@ -42,9 +43,55 @@
4243
<h3>Option #4 - Source</h3>
4344
<p>
4445
If you want to make any changes before deploying, or want to host it on any other platform not already covered
45-
above, then you can easily do so, by compiling the app from source. We've dot detailed <a href="/about/building"
46-
>Building Instructions</a
47-
>, or you can check out the docs in the repo.
46+
above, then you can easily do so, by compiling the app from source. It's very easy, and we've dot detailed
47+
<a href="/about/building">Building Instructions</a>, or you can check out the docs in the repo.
48+
</p>
49+
</section>
50+
51+
<section>
52+
<h2>Customizing</h2>
53+
<p>You can customize the branding of your instance, by setting a few environment variables. All are optional.</p>
54+
<ul>
55+
<li><code>NTB_SITE_NAME</code> - Change sitename</li>
56+
<li><code>NTB_SITE_DESCRIPTION</code> - Change site tagline</li>
57+
<li><code>NTB_SITE_ICON</code> - Set site icon</li>
58+
<li><code>NTB_HOMEPAGE_LAYOUT</code> - Set homepage layout</li>
59+
<li><code>NTB_NAVBAR_DISPLAY</code> - Set navbar display option</li>
60+
<li><code>NTB_DEFAULT_THEME</code> - Set default theme</li>
61+
<li><code>NTB_DEFAULT_LANGUAGE</code> - Set default lang</li>
62+
</ul>
63+
64+
<p>
65+
For examples on how to apply these, take a look at
66+
<a href="https://github.com/Lissy93/networking-toolbox/blob/main/.github/docs/app-customization.md">these docs</a>.
67+
</p>
68+
</section>
69+
70+
<section>
71+
<h2>Terms</h2>
72+
<p>Your only obligations are:</p>
73+
<ul>
74+
<li>
75+
Preserve the MIT license. You can view this on the <a href="/about/license">Licensing Page</a>
76+
</li>
77+
<li>
78+
You can not hold the author liable for any damages, and you understand that the software is provided "as is" with
79+
no warranties
80+
</li>
81+
<li>
82+
Not use the name "Networking Toolbox" or the logo commercially to build a competing product, without prior
83+
permission (you can rebrand it though)
84+
</li>
85+
<li>Not use the software for anything illegal, harmful, offensive, or otherwise objectionable</li>
86+
</ul>
87+
<p>
88+
Beyond that, you're free to use it however you want, for personal or commercial use. You can rebrand it, or use
89+
parts of the code in your own projects and edit anything.
90+
</p>
91+
<p>
92+
If you've found the project helpful, and want to support us, considering <a
93+
href="https://github.com/sponsors/Lissy93">sponsoring us</a
94+
> on GitHub. It always means the world to me, and helps cover ongoing running costs 🩷
4895
</p>
4996
</section>
5097

Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
/**
2+
* Customizable Settings
3+
*
4+
* This file provides default settings that can be overridden via environment variables.
5+
* All environment variables must be prefixed with NTB_ to be accessible.
6+
*
7+
* For self-hosted instances, these can be customized by setting the corresponding
8+
* environment variables. The managed instance will use the defaults.
9+
*/
10+
11+
import { env } from '$env/dynamic/public';
12+
import type { HomepageLayoutMode } from '$lib/stores/homepageLayout';
13+
import type { NavbarDisplayMode } from '$lib/stores/navbarDisplay';
14+
import type { ThemeOption } from '$lib/stores/theme';
15+
16+
// Site Branding
17+
export const SITE_NAME = env.NTB_SITE_NAME;
18+
export const SITE_TITLE = env.NTB_SITE_TITLE;
19+
export const SITE_DESCRIPTION = env.NTB_SITE_DESCRIPTION;
20+
21+
/**
22+
* Logo/icon to display in the navbar, specified as a path to an image
23+
*/
24+
export const SITE_ICON = env.NTB_SITE_ICON ?? '';
25+
26+
/**
27+
* Default homepage layout
28+
* Options: 'categories', 'default', 'minimal', 'carousel', 'bookmarks', 'small-icons', 'list', 'search', 'empty'
29+
*/
30+
export const DEFAULT_HOMEPAGE_LAYOUT: HomepageLayoutMode =
31+
(env.NTB_HOMEPAGE_LAYOUT as HomepageLayoutMode) ?? 'categories';
32+
33+
/**
34+
* Default navbar display mode
35+
* Options: 'default', 'bookmarked', 'frequent', 'none'
36+
*/
37+
export const DEFAULT_NAVBAR_DISPLAY: NavbarDisplayMode = (env.NTB_NAVBAR_DISPLAY as NavbarDisplayMode) ?? 'default';
38+
39+
/**
40+
* Default theme
41+
* Options: 'dark', 'light', 'midnight', 'arctic', 'ocean', 'purple', 'cyberpunk', 'terminal', 'lightpurple', 'muteddark', 'solarized'
42+
*/
43+
export const DEFAULT_THEME: ThemeOption = (env.NTB_DEFAULT_THEME as ThemeOption) ?? 'dark';
44+
45+
/**
46+
* Default language
47+
* Options: 'en', 'es', 'fr', 'de', etc.
48+
*/
49+
export const DEFAULT_LANGUAGE = env.NTB_DEFAULT_LANGUAGE ?? 'en';
50+
51+
/**
52+
* Primary color (for default theme). Specified as a hex code.
53+
*/
54+
export const PRIMARY_COLOR = env.NTB_PRIMARY_COLOR ?? '';

src/lib/constants/site.ts

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,12 @@
1+
import { SITE_NAME, SITE_TITLE, SITE_DESCRIPTION } from '$lib/config/customizable-settings';
2+
13
export const site = {
2-
name: 'Networking Toolbox',
3-
title: 'Networking Toolbox',
4+
name: SITE_NAME || 'Networking Toolbox',
5+
title: SITE_TITLE || 'Networking Toolbox',
46
description: 'A free set of online tools to help with IP addressing and subnetting.',
57
longDescription:
68
'Comprehensive IP address calculator with subnet calculations, CIDR conversion, IP format conversion, and network reference tools.',
7-
heroDescription: 'Your companion for all-things networking',
9+
heroDescription: SITE_DESCRIPTION || 'Your companion for all-things networking',
810
keywords: 'IP calculator, subnet calculator, CIDR converter, network tools, IP tools, networking',
911
url: 'https://networking-toolbox.as93.net',
1012
image: 'https://networking-toolbox.as93.net/og-image.png',
@@ -34,8 +36,6 @@ export const author = {
3436
url: 'https://aliciasykes.com',
3537
portfolio: 'https://as93.net',
3638
sponsor: 'https://github.com/sponsors/lissy93',
37-
// avatar: 'https://i.ibb.co/678bNCjD/alicia-sykes-184-Edit.jpg',
38-
// avatar: 'https://apps.aliciasykes.com/profile.jpg',
3939
avatar: 'https://i.ibb.co/Q7XTgybB/DSC-0444-2.jpg',
4040
};
4141

src/lib/stores/homepageLayout.ts

Lines changed: 13 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import { writable } from 'svelte/store';
22
import { browser } from '$app/environment';
3+
import { DEFAULT_HOMEPAGE_LAYOUT } from '$lib/config/customizable-settings';
34

45
export type HomepageLayoutMode =
56
| 'default'
@@ -69,18 +70,26 @@ export const homepageLayoutOptions: HomepageLayoutOption[] = [
6970
},
7071
];
7172

73+
// Validate that a layout mode is valid
74+
function isValidLayout(layout: string | null): boolean {
75+
if (!layout) return false;
76+
return homepageLayoutOptions.some((option) => option.id === layout);
77+
}
78+
7279
// Get initial value from localStorage (runs immediately on import)
7380
function getInitialLayout(): HomepageLayoutMode {
81+
// Validate DEFAULT_HOMEPAGE_LAYOUT, fallback to 'categories' if invalid
82+
const validDefault = isValidLayout(DEFAULT_HOMEPAGE_LAYOUT) ? DEFAULT_HOMEPAGE_LAYOUT : 'categories';
83+
7484
if (browser) {
7585
try {
7686
const stored = localStorage.getItem('homepage-layout');
77-
const isValidMode = homepageLayoutOptions.some((option) => option.id === stored);
78-
return isValidMode ? (stored as HomepageLayoutMode) : 'categories';
87+
return isValidLayout(stored) ? (stored as HomepageLayoutMode) : validDefault;
7988
} catch {
80-
return 'categories';
89+
return validDefault;
8190
}
8291
}
83-
return 'categories';
92+
return validDefault;
8493
}
8594

8695
function createHomepageLayoutStore() {

0 commit comments

Comments
 (0)