X-Switch Firefox add-on

This extension allows users to easily switch between back-end servers by reading out HTTP headers that contain host-name information, such as X-Server. This extension is particularly useful for developers and website administrators who need to test their website or web application on different servers. With this extension, users can quickly switch between servers without having to manually remove cookies and refresh the page. This makes testing and administration more efficient and streamlined, saving users time and effort.

IP Networks

Mobile Vikings / Proximus FTTH Dual stack Configuratie op pfSense (zonder b-box)

Vandaag kwam een Proximus technieker langs om mijn FTTH verbinding in orde te brengen. Als provider koos ik voor Mobile Vikings omdat zij een Fiber abonnement aanbieden met 1000 Mbps download en 500 Mbps upload. Dit zijn mijn eerste resultaten op pfSense:

In deze setup verbinden we een pfSense router via poort 2 (igb2) met de fiber modem op poort 1. De b-box zal hierbij overbodig worden omdat ik geen telefonie of digitale televisie afneem. Schakel de b-box nog niet onmiddellijk af. Je hebt namelijk gegevens nodig die je uit de b-box configuratie kan halen.


Arduino Airfryer

This project replaces the controller board in a Philips XXL Airfryer.

An airfryer contains the following elements:

  • Temperature sensor
  • Fan
  • Heating element
  • PSU
  • Controller board (UI)

The first three components and the relays on the power supply (PSU) board were reused in this project. Keep in mind that the relays on the PSU needs 12V. Another option is to buy 5V relays.


  • Persistent cookbook (using EEPROM memory)
  • Multiple steps when cooking (different temperatures, timings).
  • Delay cooking (act as a timer when temperature is zero)
  • Preheat option.

Simulation @ wokwi:
Unfortunately the wokwi simulation can not simulate fast rotary rotations.

Hardware Home automation

Connect LEDVANCE Smart+ remote with Philips Hue

Programming React User Interface

React – UseLocationState hook

This hook, made in typescript, can be used to change the current location state. Just use it as you would use the useState hook.

import { useHistory } from "react-router-dom";
import { useCallback } from "react";

//callback definition.
type SetStateType<T> = ((prevState: T) => T) | T;

export default <T extends any>(defaultState: T)
    : [T, (newState: SetStateType<T>) => void] => {

    const { replace, location: { state } } = useHistory<T>(); 
    const currentState = isNullOrUndefined(state) ? defaultState : state;

    const setState = useCallback((newState: SetStateType<T>) => {
        const state = (newState instanceof Function)
            ? newState(currentState)
            : newState;
        state !== currentState && replace({ state });
    }, [replace, currentState]);

 return [currentState, setState];

UPDATE Jan 2022: Simplified version using useState():

import { useHistory } from "react-router-dom";
import { useEffect, useState } from "react";

//callback definition.
type SetStateType<T> = ((prevState: T) => T) | T;

const useLocationState = <T extends any>(defaultState: T)
    : [T, (newState: SetStateType<T>) => void] => {

    const { replace, location } = useHistory<T>();
    const [state, setState] = useState<T>(location.state || defaultState);

    //save state in locationState
    useEffect(() => {
        location.state !== state && replace({ state });        
    }, [replace, state, location.state])

    return [state, setState];

export default useLocationState;


import * as React from 'react';
import useLocationState from '../UseLocationState';

export default (() => {
    const [someState, setSomeState] = useLocationState({ test: 1 });

    //change location state (2 options)
    useEffect(() => {
        //option 1
        setSomeState({ test: 10 });
        //option 2
        setSomeState(prev => ({ test: prev.test - 5 })) ;
    }, [setSomeState]);

    return <>{someState}</>


Apache – Password protected Directories with Require SSL

Prepend the following code in an .htaccess file

RewriteEngine On
RewriteCond %{HTTP_HOST} ^http://example\.com$ [NC]
RewriteRule ^(.*)$$1 [L,R=301]

##Uncomment for static React hosting (enables client routing)
#RewriteCond %{REQUEST_FILENAME} !-f
#RewriteRule ^ index.html [QSA,L]

AuthGroupFile /dev/null
AuthType Basic
AuthUserFile /home/.htpasswd
AuthName "Some message..."
require valid-user
ErrorDocument 401 "Unauthorized Access"

This configuration redirects all requests to its https equivalent and will also work with password protected directories. Authentication is performed over SSL, never over http.

Check if the htpassword exists. Of not, create new users using this command

#Crypt encryption
htpasswd -bd .htpasswd USER PWD

#SHA encryption
htpasswd -bs .htpasswd USER PWD

Environment Variables in Net Core 3 with React and Docker

This code replaces React Environment Variables with docker variables at runtime (first run only!). This makes it possible to present different environment vars at startup instead of at build time. This is especially useful when using docker containers. You can make one docker image for different environments.

Development mode : You can still use .env files (as described in react documentation). Nothing changed here.

Production or other build modes: The react environment vars will be replaced in the static html file at startup.

This approach has as advantage that you do not need to inject vars on every single page request (dynamic content). This solution changes the variables only once on startup and keeps the file static throughout the program runtime. This also means that this code cannot be used for variables that changes between requests.

User Interface

React Prompt on page unload (Typescript)

This React Prompt Component allows you to show a dialog before closing a page or when navigating to another page. This is an extension on the existing prompt component within React which only shows dialog messages when navigating with React Router. This component works in hooks and class components.

Copy paste the code below and save it as DirtyPrompt.tsx