This is a submission for the Neon Open Source Starter Kit Challenge : Ultimate Starter Kit
My Kit
This starter kit is called Neon Max. I planned and develop this kit with the Laravel PHP framework in mind. I have always loved how much Laravel provides right out of the box, including database integration. It was one of my first full-stack framework I learned.
However, nowadays I mostly develop with Next.js because I prefer developing the frontend with React; it's not as easy to integrate Laravel with React. Next.js also comes with a lot base features; but I think Laravel beats it in terms of how much functionality is prepared for you.
So I created this so that the next time I want to develop a website, I can have the prepared functionalities of Laravel and still be able to integrate React easily.
Firstly, I wanted to integrate Neon's serverless Postgres database into the starter kit, not only as the default database, but I'm also using it so I can run raw queries immediately. I'm using @neondatabase/serverless
so you can run flexible queries like:
import { neon } from "@neondatabase/serverless";
const sql = neon(process.env.DATABASE_URL);
const response = await sql`SELECT version()`;
Features
A comprehensive list of features can be found at the documentation, so I'll keep it brief here.
Authentication
A working authentication system comes with Neon Max. It uses Next Auth to handle all the authentication flow, including session management.
There's also the Auth
helper class in lib/auth.ts
that will help you protect authenticated pages as well as limit page access to guest users (eg. login and register pages).
// protected pages
await Auth.authenticated();
// guest pages
await Auth.guest();
Authorization
Beyond authentication, you can add another layer of security with authorization. There's an Authorization
helper class in lib/authorization.ts
.
First, define what's called a "policy" in config/authorization.ts
:
export const AUTHORIZATIONS = {
"can-edit-blog": async (user, blogId: number) => {
const blog = await getBlogById(blogId);
if (blog && blog.authorId === user.id) return true;
return false;
},
};
Then, use it in a server context to determine if the current authenticated user passes a specified policy:
{(await Authorization.allows("can-edit-blog", blog.id)) && (
<button>Edit Blog</button>
)}
Error Handling
There's also an Errors
helper class with a bunch of methods that you can use to handle errors.
Set General Error
import { Errors } from "@/lib/errors";
const isPasswordValid = await checkPassword(password);
// set the error
if(!passwordValid) {
Errors.set("authError", "Incorrect credentials");
}
// Flash all errors
Errors.flash();
Then, you can render the error on the front-end using Errors.get()
. You can use the <ErrorMessage/>
component provided in the starter kit. This was inspired by Laravel @error
directive:
<ErrorMessage message={Errors.get("authError")}/>
Validating Zod Schema and Generating Appropriate Errors
There's also a Errors.validateZod()
method. This method is pretty powerful, as you just need to supply it with a Zod schema and the data you want to validate against it. This will automatically generate the errors and flash them as if you did Errors.set()
and Errors.flash()
manually:
const title = formData.get("title") as string;
const content = formData.get("content") as string;
const postValidationResult = Errors.validateZod(postSchema, { title, content });
if(postValidationResult.error) {
redirect("/post/create");
}
You can then use the auto-generated errors by referencing the field names defined in the schema:
<ErrorMessage message={Errors.get("title")}/>
<ErrorMessage message={Errors.get("content")}/>
Link to Kit
The kit, along with its setup instructions can be found over at its Github repo:
https://github.com/AnsellMaximilian/neon-max-starter-kit
Other related links
Your Journey
Had a lot of fun developing this starter kit, as this was my first one. It was also cool learning about Neon. I'm always looking for data storage solutions for my Next.js apps, and I've definitely added Neon to the list.
I always love good services that provide a free plan to test things out.
Top comments (0)