In the previous blog, we covered the basics of Sveltekit (features, project structure ), in this blog we will be implementing a simple login page with validation using Zod, a library used for validation.
Check out this blog for basics of Sveltekit!
Initial Setup:
- Navigate to the desired directory where you want to initialize your project, then execute the following commands:
Go ahead and open the project in any code editor, I will be using VS Code.
Please refer to the previous blog for a detailed explanation of the project structure. It provides all the necessary clarifications on that aspect.
Configuration & Implementation:
Verify if the project setup has been done, correctly. To run the development server enter the following commands in the project directory:
npm install
npm run dev
After running the commands you will get something like this if the setup is correct:
if you head to localhost:5173 , you will see something like this:
Now we start editing the +page.svelte file in the src/routes , this represents the home route.
The general format of a sveltekit code is as shown below:
<script>
// This section includes JavaScript code for logic and data handling
</script>
<main>
<!-- This section contains HTML markup for the page structure -->
</main>
<style>
/* This section holds CSS styles for the component's presentation */
</style>
For the sigmup form we will be validating the email and password for which , we will be using Zod, third party library for validation , install it using this command:
npm i zod
- Now we write a script to route the request from the home (current directory) to the /signup ,we will be adding a simple <a> for this and will use goto function that helps in routing from one page to another.
Main Page:
- Add the following piece of code to the <script></script>:
<script>
import { goto } from "$app/navigation";
const navigateToSignup = () => {
goto("/signup");
};
</script>
Summarizing the above piece of code:
This script sets up a function to navigate users to the /signup page. It imports the goto function from $app/navigation and defines navigateToSignup, which uses goto to redirect the user.
Next, we’ll add the markup code for this part.
<main>
<h1>Welcome to Our Application!</h1>
<p>
We are excited to have you here. Click the button below to get started with
signing up.
</p>
<button on:click={navigateToSignup}>Go to Signup</button>
</main>
Summarizing the above code:
The following code snippet creates a welcoming main page for the application. It includes a heading, a brief introductory paragraph, and a button. Clicking the button will navigate the user to the signup page.
Next , we have the CSS code that adds basic styling to the page:
<style>
main {
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
height: 100vh;
text-align: center;
}
button {
padding: 10px 20px;
font-size: 16px;
cursor: pointer;
margin-top: 20px;
}
</style>
After adding the above piece of code the total script should look like this:
<script>
import { goto } from "$app/navigation";
// Function to navigate to the /signup page
const navigateToSignup = () => {
goto("/signup");
};
</script>
<main>
<h1>Welcome to Our Application!</h1>
<p>
We are excited to have you here. Click the button below to get started with
signing up.
</p>
<button on:click={navigateToSignup}>Go to Signup</button>
</main>
<style>
main {
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
height: 100vh;
text-align: center;
}
button {
padding: 10px 20px;
font-size: 16px;
cursor: pointer;
margin-top: 20px;
}
</style>
After adding the above code , go to the browser , the page should look something like this:
Signup Page:
Head over to the src/routes and create a new folder called "signup", this represents the signup route(/signup). In the folder create a new file called "+page.svelte", this represents the main page of the signup route.
First, we include the JavaScript part that has the imports and some validation functions, include the following in the <Script></Script> part:
<script>
import { goto } from "$app/navigation";
import { z } from "zod";
let email = "";
let password = "";
const emailSchema = z
.string()
.email({ message: "Kindly enter a valid Email!" });
const passwordSchema = z
.string()
.min(8, {
message: "The password should contain a minimum of 8 characters!",
})
.max(10, {
message: "The password should contain a maximum of 10 characters!",
});
const validate = () => {
try {
emailSchema.parse(email);
passwordSchema.parse(password);
return true;
} catch (error) {
if (error.errors) {
error.errors.forEach((err) => alert(err.message));
}
return false;
}
};
const handleSubmit = (event) => {
event.preventDefault();
if (validate()) {
alert("Response Captured!");
}
};
</script>
Summarising the above code:
Imports: The script imports goto from $app/navigation and zod
State: Initializes email and password variables.
Validation: Defines emailSchema and passwordSchema to validate email and password inputs.
Validation Function: The validate function checks inputs against schemas and shows alerts for validation errors.
Submit Handler: handleSubmit prevents default form submission and shows a success alert if validation passes.
Next, we look at structuring the page (HTML) part.
<main>
<div class="card">
<h2>Signup</h2>
<form on:submit={handleSubmit}>
<div class="form-group">
<label for="email">Email:</label>
<input
type="email"
id="email"
bind:value={email}
placeholder="Enter your email"
required
/>
</div>
<div class="form-group">
<label for="password">Password:</label>
<input
type="password"
id="password"
bind:value={password}
placeholder="Enter your password"
required
/>
</div>
<button type="submit">Signup</button>
</form>
</div>
</main>
Summarising the above piece of code
This code snippet defines the layout and functionality for a signup page. It features a card-style container with a heading and a form. The form includes required fields for entering an email and a password, and it includes a function to handle form submission. A submit button is provided to submit the form.
Next, we have the CSS that provides basic styling and positioning for the page, including the card and form elements.
<style>
main {
display: flex;
align-items: center;
justify-content: center;
height: 100vh;
background-color: #f0f0f0;
}
.card {
background: white;
padding: 2rem;
border-radius: 8px;
box-shadow: 0 4px 8px rgba(0, 0, 0, 0.1);
width: 100%;
max-width: 400px;
text-align: center;
}
.form-group {
margin-bottom: 1.5rem;
text-align: left;
}
label {
display: block;
margin-bottom: 0.5rem;
font-weight: bold;
}
input {
width: 100%;
padding: 0.75rem;
font-size: 1rem;
border-radius: 4px;
border: 1px solid #ccc;
}
button {
width: 100%;
padding: 0.75rem;
font-size: 1rem;
cursor: pointer;
background-color: #007bff;
color: white;
border: none;
border-radius: 4px;
}
button:hover {
background-color: #0056b3;
}
</style>
After adding all the code the script should look like this:
<script>
import { goto } from "$app/navigation";
import { z } from "zod";
let email = "";
let password = "";
const emailSchema = z
.string()
.email({ message: "Kindly enter a valid Email!" });
const passwordSchema = z
.string()
.min(8, {
message: "The password should contain a minimum of 8 characters!",
})
.max(10, {
message: "The password should contain a maximum of 10 characters!",
});
const validate = () => {
try {
emailSchema.parse(email);
passwordSchema.parse(password);
return true;
} catch (error) {
if (error.errors) {
error.errors.forEach((err) => alert(err.message));
}
return false;
}
};
const handleSubmit = (event) => {
event.preventDefault();
if (validate()) {
alert("Response Captured!");
}
};
</script>
<main>
<div class="card">
<h2>Signup</h2>
<form on:submit={handleSubmit}>
<div class="form-group">
<label for="email">Email:</label>
<input
type="email"
id="email"
bind:value={email}
placeholder="Enter your email"
required
/>
</div>
<div class="form-group">
<label for="password">Password:</label>
<input
type="password"
id="password"
bind:value={password}
placeholder="Enter your password"
required
/>
</div>
<button type="submit">Signup</button>
</form>
</div>
</main>
<style>
main {
display: flex;
align-items: center;
justify-content: center;
height: 100vh;
background-color: #f0f0f0;
}
.card {
background: white;
padding: 2rem;
border-radius: 8px;
box-shadow: 0 4px 8px rgba(0, 0, 0, 0.1);
width: 100%;
max-width: 400px;
text-align: center;
}
.form-group {
margin-bottom: 1.5rem;
text-align: left;
}
label {
display: block;
margin-bottom: 0.5rem;
font-weight: bold;
}
input {
width: 100%;
padding: 0.75rem;
font-size: 1rem;
border-radius: 4px;
border: 1px solid #ccc;
}
button {
width: 100%;
padding: 0.75rem;
font-size: 1rem;
cursor: pointer;
background-color: #007bff;
color: white;
border: none;
border-radius: 4px;
}
button:hover {
background-color: #0056b3;
}
</style>
After adding the code, head over to localhost:5173/signup, it should look something like this:
Output Screens:
This article covered the implementation part of SvelteKit using a simple example where we had a main page and we added a signup page where users can navigate from the main page. The signup page features a simple card component with email and password input fields that are validated using custom schema validation with Zod.
In the next blog, we will be covering some more concepts related to Sveltekit, until then stay tuned!