Fix Client/Server Time Zone Mismatches with SvelteKit Progressive Enhancement

I have yet to encounter a developer who enjoys working with time zones. I’ve run into my fair share of bugs brought about by these annoying geographical regions. However, this issue in particular was the perfect storm of HTML components, SvelKit functionality, and client-server mismatches. Luckily I could use this as an opportunity to learn about a useful SvelteKit feature, progressive enhancement, that will be a huge help in the future.

The common problem

I was working on an app that used a common  HTML date time picker. This component can save you a lot of time when building out a form, but there is a drawback. When you submit the form, the input will be recorded in the user’s local time. If the client and server code is running in the same time zone this is not a problem, but that is not always the case. This can be especially tricky because it will work locally, and you often won’t notice an issue until you deploy your code.

The simple solution

As you might already be thinking, there is a simple solution to this: just use UTC time. This way, no matter what time zone the client or server is in, they will be talking about time in the same way. That is a great solution, but to set it up in SvelteKit, you will need to understand two key features. From actions and Progressive enhancement. Next, I’ll talk about how both of these work and how you can use the combination to implement our solution.

Form actions

By default, every +page.server file in SvelteKit gives you the option to export actions. You can use the default action, which will be used for any unspecified post request made to the server. Or, you can create named actions that can be called specifically when submitting post requests to the server. This works great for most use cases and greatly simplifies form submission in the site. These endpoints will automagically serialize a form submission for you. You can access this via a request object server side. If the action is completed successfully, the load function will be called and the whole page will be refreshed. However, there are times when you may want a little more control of this process, that is where another SvelKit feature comes into play.

Progressive enhancement

There are different levels of control we can achieve with this tool. In the simplest case, adding use:enhance to a form element will stop the page from reloading when a form submission is completed successfully. From there, we can expand the functionality further. If you want to trigger an action based on the result, you can pass a function into use:enhance.


<form
    method=”POST”
    use:enhance = () => {
        return async (response) => {
            //Access the Action result and perform any post submission actions
        };
    };
>

Not only will progressive enhancement allow you to use the result of an action, but it also allows you to augment the data before you send it to the server.


<form
    method=”POST”
    use:enhance = ({ formData }) => {
         //Access the formData here before it makes it to the server. 
        return async (response) => {
            //Access the Action result and perform any post submission actions
        };
    };
>

To solve the original problem

That brings us full circle, back to the original problem. The form uses the client’s local time, but the server isn’t using the same time zone. Using progressive enhancements, we can transform the local date time to UTC before it’s sent to the server.


<form
    method=”POST”
    use:enhance = ({ formData }) => {
        const inputDate = formData.get("inputDate");
        if (inputDate) {
              formData.set("inputDate", new Date(inputDate.toString()).toISOString());
        }
        return async (response) => {
            //Access the Action result and perform any post submission actions
        };
    };
>

This is a simple use case for this powerful tool, but I hope it helps illustrate the utility of progressive enhancement.

Conversation

Join the conversation

Your email address will not be published. Required fields are marked *