DEV Community

Cover image for Neon Max Starter Kit
Ansell Maximilian
Ansell Maximilian

Posted on

Neon Max Starter Kit

This is a submission for the Neon Open Source Starter Kit Challenge : Ultimate Starter Kit

My Kit

Kit home page

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()`;
Enter fullscreen mode Exit fullscreen mode

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();
Enter fullscreen mode Exit fullscreen mode

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;
  },
};
Enter fullscreen mode Exit fullscreen mode

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>
)}
Enter fullscreen mode Exit fullscreen mode

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();
Enter fullscreen mode Exit fullscreen mode

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")}/>
Enter fullscreen mode Exit fullscreen mode
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");
}
Enter fullscreen mode Exit fullscreen mode

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")}/>
Enter fullscreen mode Exit fullscreen mode

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)