Trigger

Forward

This project began a fork of sui, an open source home page designed as a simple landing page with applications and bookmarks. As I started using it, it became clear that longer use would be made tedious by having to manually update JSON files every time I wanted to add something. An updated project, flame, exists; however, flame is intended to run on docker, which I am not a fan of in my environment. I also had a need to learn React, and so I started on my own version. I then began rewriting sui in React with TypeScript instead of it's native JavaScript, and added a MariaDB database for storage. The result was a highly customizable home page for any browser or device.

Repositories

Front end
Back end

Technologies Used

-React/TS with various packages
-Vite
-Nodejs + NPM
-Mantine Component Library
-MariaDB server
-pm2
-VSCode
-NGINX
-Git/Gitea

Reasoning and Challenges

As mentioned above, one of the main challenges was having to update JSON files every time you need to update any entry. This was compounded when trying to update themes, as they also had static entries in the JS and CSS files. There was no way to update anything via the front end.

Example applications
An example bookmark category with bookmarks
Themes were hardcoded into themer.js in the original project.
Themes in the original CSS file that correlate to the previous screenshot

These are not very feature rich objects either. Moving forward, everything also needs to be able to be updated from the front end, otherwise it wouldn't be very convenient of a home page. At this point it just made sense to start the back end Node.js server and create a database for storage. Not to mention this is a lot easier in my opinion than reading and writing back JSON files and worrying about formatting.

Columns were added to every datatype to allow for more customization. This is an updated Theme object from the MariaDB table.
Truncated image showing Node.js server CRUD operations. All query strings are escaped for sanitation.

As a result, I needed to create front end elements to handle all of these operations. I created several multipurpose Modals using the Mantine Component Library to help with development time. These Modals accept a ReactNode object for it's "body" and present the user with a basic form.

Truncated screenshot of the Add Application modal. Theme styles are implemented primarily through CSS modules for Mantine, but certain functions use front end logic, like adding what I have called 'textShadows' to TextInput fields.
Form for a new application. Fields also validate data on submission.

Front end changes wouldn't be any fun without a notification letting you know your changes were successful for not, so I also added basic notifications on all API calls to let the user know the request fired and a response was returned.

Updating this object on the applications endpoint was successful
Successful request notification resolution

For convenience on the development side, the API code has been fully configured to reach either the production or development environments that the user configures.

This is a much more convenient model for the user to manage their home page items. Even before this part was complete, however, I had already updated the structure of the original project when converting it to React.

The original structure was extremely simple.

Inside index.html you can find regular HTML and JavaScript blocks enumerating things like the applications.

The icons used above had to be MDI icons and looked up before hand, making customization even more tedious.

My implementation ends up being quite a bit more complicated in code, due mostly to handling states, new customization features, and TanStack queries.

Truncated snipped from Hompage.tsx, showing the React Nodes replacing the original HTML sections.
Code showing implementation of TanStack Query to call the API to retrieve data. Custom Types have been created for all items on the home page.
Truncated code showing the return block from Applications.tsx

Since this was intended to be a learning project for React+TS, I decided to break out as many components as possible for practice. This lead to quite a few files, but an easy to follow structure.

Features

Responsive search bar with history and items from Applications and Bookmarks
Different providers can be configured to use in the search bar with a prefix
Search history management built on TanStack Table and Query
Welcome messages greet the user based on time of day, and custom messages can be added which are displayed at random. Weather information comes from the weather.gov API, and requires no key or additional setup other than the user's preferred address.
Clicking on the temperature in the header or typing !weather into the search bar will present the user with more detailed weather information

Applications

The application section is configured from the settings page, which shares this AppItem component. The density and size of the component can be changed for user customization, as well as reuse in code.
These are the same component as the image above
The pop out for editing an entry

Bookmarks

The bookmark section is configured from the settings page as well, but Bookmarks are further categorized into Groups. This allows for granular filtering and sorting for user customization.
Users are able to add bookmarks and rearrange items in the groups, and the groups themselves

Settings Button

The user can save themes to the database in playlists for convenient use later. The component on the right side controls the layout of the application and bookmark sections of the main home page. Changes to preferences here are stored in local storage to persist between sessions.

Theming

The two biggest challenges with sui and flame were customization and theming. Customization was easily fixed by adding the database and API server to allow for updating items on the home page front end. I was using an editable table while development was in progress to view and edit themes, but there was no preview, color picker, or other useful visual elements, and all fields were just strings. But I did want to solve both of those issues going in, which resulted in a fully fledged theme builder and playlist management for user generated themes. While somewhat basic, it allows for fairly great expression of creativity.

Themes are shown as in the "background" when they are not part of the current playlist - themes are grayscale if they have been removed from the shuffle of the All Themes playlist
The theme builder modal
Backgrounds can be uploaded and managed, and are stored on the disk through the Node back end
When an image is uploaded, it is resized once as a "full sized" image and once as a thumbnail
Playlists define which themes are displayed at random when the home page loads

Technical

The page is being served through an NGINX reverse proxy, and the back end API server has been separated into it's own package so that it can be located on a different server if necessary. Relevant connection details are in .env files for the user to configure.

The user has the option to change the base url of the server so that they may choose to either serve it at the root of the domain, a subdomain, or a URI slug.

The page does not handle authentication directly, and relies on NGINX to handle an auth-request to allow a user to reach the page. If they do not have authorization, they are redirected to a 401.

The back end Node.js server and front end Vite project have both been setup to run using pm2 as services.


When used together you can make a very useful and easy to change home page.

Screenshots

This was the original UI for sui. No additional UI elements were included beyond buttons to switch themes in the bottom left menu