<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>Forem: Carsten Lebek</title>
    <description>The latest articles on Forem by Carsten Lebek (@carstenlebek).</description>
    <link>https://forem.com/carstenlebek</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F1017935%2Fb22d6f34-3d5a-474e-ba39-4eefb738791c.jpeg</url>
      <title>Forem: Carsten Lebek</title>
      <link>https://forem.com/carstenlebek</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://forem.com/feed/carstenlebek"/>
    <language>en</language>
    <item>
      <title>Svelte + TailwindCSS: A Winning Combo for Shopify Theme App Extensions</title>
      <dc:creator>Carsten Lebek</dc:creator>
      <pubDate>Tue, 12 Sep 2023 10:18:42 +0000</pubDate>
      <link>https://forem.com/carstenlebek/svelte-tailwindcss-a-winning-combo-for-shopify-theme-app-extensions-im8</link>
      <guid>https://forem.com/carstenlebek/svelte-tailwindcss-a-winning-combo-for-shopify-theme-app-extensions-im8</guid>
      <description>&lt;p&gt;If you're a Shopify developer, you know the drill—creating theme app extensions often involves wrestling with vanilla JavaScript, CSS, and Liquid templates. While these are powerful tools in their own right, the developer experience can sometimes leave much to be desired. Tangled code, cumbersome workflows, and limited modularity can slow down your development process and increase the risk of bugs.&lt;/p&gt;

&lt;p&gt;Enter the world of modern front-end frameworks, where Developer Experience (DX) takes center stage. Frameworks like React, Angular, and Vue have shifted the paradigm, but today, I want to introduce you to a tool that's truly a cut above the rest when it comes to Shopify theme extension development: Svelte, combined with the utility-first magic of TailwindCSS.&lt;/p&gt;

&lt;p&gt;Why Svelte? Unlike traditional frameworks that run in the browser, Svelte is compiled. This means it converts your components into highly efficient vanilla JavaScript at build time, resulting in smaller bundle sizes. This is especially critical for Shopify stores, where every millisecond of load time can impact customer experience and, ultimately, conversions. With Svelte, you get to enjoy the perks of a modern development framework without bloating your online store.&lt;/p&gt;

&lt;h2&gt;
  
  
  Building a Shopify Theme App Extension with Svelte and TailwindCSS: A Step-by-Step Tutorial
&lt;/h2&gt;

&lt;p&gt;In this tutorial, we'll walk through the steps to set up a Shopify theme app extension using Svelte and TailwindCSS. By the end, you'll have a fully functional extension that benefits from Svelte's smaller bundle size and the utility-first magic of TailwindCSS. Let's get started!&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Step 1: Use the Template Repository&lt;/strong&gt;&lt;br&gt;
Firstly, navigate to the &lt;a href="https://github.com/carstenlebek/svelte-app-extension" rel="noopener noreferrer"&gt;Svelte App Extension&lt;/a&gt; repository by Carsten Lebek. Click on the "Use this template" button to create a new repository based on this template.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Step 2: Clone the Repository&lt;/strong&gt;&lt;br&gt;
Clone the newly created repository onto your local machine. Open your terminal and execute the following:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;git clone &amp;lt;Your-Repository-URL&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Replace  with the URL of your new repository.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Step 3: Install Dependencies&lt;/strong&gt;&lt;br&gt;
Navigate to the directory where you've cloned the repository and run the following command to install all necessary dependencies:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;pnpm &lt;span class="nb"&gt;install&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Step 4: Link the App to Shopify&lt;/strong&gt;&lt;br&gt;
Run the following command to link your local development environment with an existing or a new app in your Shopify Partners Dashboard:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;pnpm config:link
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Follow the prompts to complete the linking process.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Step 5: Start Development and Install the App&lt;/strong&gt;&lt;br&gt;
Run the development server using the following command:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;pnpm dev
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;After the development server starts, you'll be prompted with a message. Press 'p' to install the app.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Step 6: Add the Extension to Your Theme&lt;/strong&gt;&lt;br&gt;
Finally, open your Shopify theme editor and add the new theme app extension section.&lt;/p&gt;

&lt;h2&gt;
  
  
  What's Next?
&lt;/h2&gt;

&lt;p&gt;You've successfully set up your development environment to build a Shopify theme app extension using Svelte and TailwindCSS. Your project files are located in &lt;code&gt;./theme-extension&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Inside this directory, you'll find examples on how to make settings available within the Shopify theme editor and how to use those settings within your Svelte components. This empowers you to create highly dynamic and customizable extensions with ease.&lt;/p&gt;

&lt;p&gt;Feel free to dive into the code and explore the full potential of Svelte and TailwindCSS in elevating your Shopify theme development experience.&lt;/p&gt;

&lt;p&gt;Happy coding! 🚀&lt;/p&gt;

</description>
      <category>svelte</category>
      <category>shopify</category>
      <category>javascript</category>
    </item>
    <item>
      <title>Svelte Email - Build and design emails with Svelte</title>
      <dc:creator>Carsten Lebek</dc:creator>
      <pubDate>Sat, 04 Feb 2023 15:47:33 +0000</pubDate>
      <link>https://forem.com/carstenlebek/svelte-email-build-and-design-emails-with-svelte-5f33</link>
      <guid>https://forem.com/carstenlebek/svelte-email-build-and-design-emails-with-svelte-5f33</guid>
      <description>&lt;p&gt;Email is one of the most widely used forms of communication in the modern world, but developing them can be a real pain in the ass. Whether it's formatting issues, limited design options, or simply struggling to come up with compelling content, the process of creating an effective email can be frustrating and time-consuming.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://react.email/" rel="noopener noreferrer"&gt;React Email&lt;/a&gt; has made the experience a lot better, so I've decided to build something similar for Svelte.&lt;/p&gt;

&lt;p&gt;With &lt;a href="https://github.com/carstenlebek/svelte-email" rel="noopener noreferrer"&gt;Svelte Email&lt;/a&gt; you can start building, designing and sending emails in your SvelteKit project in literally three easy steps.&lt;/p&gt;

&lt;h2&gt;
  
  
  Step 1: Installation
&lt;/h2&gt;

&lt;p&gt;Install the package to your existing SvelteKit project:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;npm &lt;span class="nb"&gt;install &lt;/span&gt;svelte-email
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;pnpm add svelte-email
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Step 2: Create an email template using Svelte
&lt;/h2&gt;

&lt;p&gt;&lt;code&gt;src/$lib/emails/Hello.svelte&lt;/code&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;script&amp;gt;&lt;/span&gt;
    &lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;Button&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;Hr&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;Html&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;Text&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;svelte-email&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

    &lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;name&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;World&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/script&amp;gt;&lt;/span&gt;

&lt;span class="nt"&gt;&amp;lt;Html&lt;/span&gt; &lt;span class="na"&gt;lang=&lt;/span&gt;&lt;span class="s"&gt;"en"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;Text&amp;gt;&lt;/span&gt;
        Hello, {name}!
    &lt;span class="nt"&gt;&amp;lt;/Text&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;Hr&lt;/span&gt; &lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;Button&lt;/span&gt; &lt;span class="na"&gt;href=&lt;/span&gt;&lt;span class="s"&gt;"https://svelte.dev"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;Visit Svelte&lt;span class="nt"&gt;&amp;lt;/Button&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/Html&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Step 3: Send an email
&lt;/h2&gt;

&lt;p&gt;This example uses &lt;a href="https://nodemailer.com/about/" rel="noopener noreferrer"&gt;Nodemailer&lt;/a&gt; to send the email. You can use any other email service provider.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;src/routes/emails/hello/+server.js&lt;/code&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;render&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;svelte-email&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;Hello&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;$lib/emails/Hello.svelte&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;nodemailer&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;nodemailer&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;transporter&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;nodemailer&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;createTransport&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
    &lt;span class="na"&gt;host&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;smtp.ethereal.email&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;port&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;587&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;secure&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;auth&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="na"&gt;user&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;my_user&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="na"&gt;pass&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;my_password&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;emailHtml&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;render&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
    &lt;span class="na"&gt;component&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;Hello&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;props&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Svelte&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;options&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="na"&gt;from&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;you@example.com&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;to&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;user@gmail.com&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;subject&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;hello world&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;html&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;emailHtml&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;

&lt;span class="nx"&gt;transporter&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;sendMail&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;options&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Congratulations 🎉 You have just sent an email from a server route in your SvelteKit project, without ever having to touch the HTML of the email.&lt;/p&gt;

&lt;p&gt;Sending emails arguably can't get easier than this.&lt;/p&gt;

&lt;p&gt;Check out the docs for Svelte Email and start building emails with ease! &lt;a href="https://svelte-email.vercel.app/docs/overview/svelte-email" rel="noopener noreferrer"&gt;Documentation&lt;/a&gt;&lt;/p&gt;

</description>
      <category>svelte</category>
      <category>webdev</category>
      <category>javascript</category>
      <category>opensource</category>
    </item>
    <item>
      <title>Credentials Authentication with Database Sessions Using Auth.js, SvelteKit and Prisma</title>
      <dc:creator>Carsten Lebek</dc:creator>
      <pubDate>Tue, 31 Jan 2023 08:32:18 +0000</pubDate>
      <link>https://forem.com/carstenlebek/credentials-authentication-with-database-sessions-using-authjs-sveltekit-and-prisma-2epm</link>
      <guid>https://forem.com/carstenlebek/credentials-authentication-with-database-sessions-using-authjs-sveltekit-and-prisma-2epm</guid>
      <description>&lt;p&gt;This guide will show you how to get started with implementing credentials authentication using Auth.js, Sveltekit, and Prisma, while utilizing database sessions.&lt;/p&gt;

&lt;h1&gt;
  
  
  Step 1: Installing Dependencies
&lt;/h1&gt;

&lt;p&gt;First, you'll need to install the necessary packages. In your Sveltekit project, run the following commands:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;pnpm i prisma @prisma/client @auth/core @auth/sveltekit bcrypt
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h1&gt;
  
  
  Step 2: Create your Prisma Schema
&lt;/h1&gt;

&lt;p&gt;Create a file named schema.prisma and paste the following code:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;datasource db {
  provider = "postgresql"
  url      = env("DATABASE_URL")
  shadowDatabaseUrl = env("SHADOW_DATABASE_URL") // Only needed when using a cloud provider that doesn't support the creation of new databases, like Heroku. Learn more: https://pris.ly/migrate-shadow
}

generator client {
  provider        = "prisma-client-js"
}

model Account {
  id                 String  @id @default(cuid())
  userId             String
  type               String
  provider           String
  providerAccountId  String
  refresh_token      String?  @db.Text
  access_token       String?  @db.Text
  expires_at         Int?
  token_type         String?
  scope              String?
  id_token           String?  @db.Text
  session_state      String?

  user User @relation(fields: [userId], references: [id], onDelete: Cascade)

  @@unique([provider, providerAccountId])
}

model Session {
  id           String   @id @default(cuid())
  sessionToken String   @unique
  userId       String
  expires      DateTime
  user         User     @relation(fields: [userId], references: [id], onDelete: Cascade)
}

model User {
  id            String    @id @default(cuid())
  name          String?
  email         String?   @unique
  emailVerified DateTime?
  image         String?
  accounts      Account[]
  sessions      Session[]
  username      String?   @unique
  password      String?
}

model VerificationToken {
  identifier String
  token      String   @unique
  expires    DateTime

  @@unique([identifier, token])
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h1&gt;
  
  
  Step 3: Create the database schema with Prisma Migrate
&lt;/h1&gt;

&lt;p&gt;Run the following command to create the database schema:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;npx prisma migrate dev
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This will create an SQL migration file and execute it.&lt;/p&gt;

&lt;p&gt;Note that you will need to specify your database connection string in the environment variable &lt;code&gt;DATABASE_URL&lt;/code&gt;. You can do this by setting it in a &lt;code&gt;.env&lt;/code&gt; file at the root of your project.&lt;/p&gt;

&lt;h1&gt;
  
  
  Step 4: Initialize the Prisma client
&lt;/h1&gt;

&lt;p&gt;Create a file named client.ts in the src/lib/prisma directory and paste the following code:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;// src/lib/prisma/client.ts

import {  PrismaClient } from '@prisma/client';

import { NODE_ENV } from '$env/static/private';

declare global {
    // eslint-disable-next-line no-var
    var prisma: PrismaClient | undefined;
}

export const prisma =
    global.prisma ||
    new PrismaClient({
        // * Uncomment this to see the SQL queries in the console
        // log: NODE_ENV === 'development' ? ['query', 'error', 'warn'] : ['error']
    });

if (NODE_ENV !== 'production') {
    global.prisma = prisma;
}

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h1&gt;
  
  
  Step 5: Set up the SvelteKit Server Hooks
&lt;/h1&gt;

&lt;p&gt;In this step, you will create a server hooks file in your SvelteKit project to handle authentication with &lt;a class="mentioned-user" href="https://dev.to/auth"&gt;@auth&lt;/a&gt;/sveltekit. You will also import the necessary dependencies such as CredentialsProvider from &lt;a class="mentioned-user" href="https://dev.to/auth"&gt;@auth&lt;/a&gt;/core, PrismaAdapter from @next-auth/prisma-adapter, and bcrypt for password encryption.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;// src/hooks.server.ts

import { SvelteKitAuth } from '@auth/sveltekit';
import CredentialsProvider from '@auth/core/providers/credentials';
import type { Handle } from '@sveltejs/kit';
import { PrismaAdapter } from '@next-auth/prisma-adapter';
import type { Adapter } from '@auth/core/adapters';
import { prisma } from '$lib/prisma/client';
import type { Provider } from '@auth/core/providers';
import { encode, decode } from '@auth/core/jwt';
import bcrypt from 'bcrypt';

export const handle: Handle = async ({ event, resolve }) =&amp;gt; {
    const result = await SvelteKitAuth({
        adapter: PrismaAdapter(prisma) as Adapter,
        providers: [
            CredentialsProvider({
                // The name to display on the sign in form (e.g. "Sign in with...")
                name: 'Credentials',
                // `credentials` is used to generate a form on the sign in page.
                // You can specify which fields should be submitted, by adding keys to the `credentials` object.
                // e.g. domain, username, password, 2FA token, etc.
                // You can pass any HTML attribute to the &amp;lt;input&amp;gt; tag through the object.
                credentials: {
                    username: { label: 'Username', type: 'text', placeholder: 'Username' },
                    password: { label: 'Password', type: 'password' }
                },
                async authorize(credentials) {
                    if (!credentials) {
                        return null;
                    }

                    const user = await prisma.user.findUnique({
                        where: {
                            username: credentials.username
                        }
                    });

                    if (!user || !user.password) {
                        return null;
                    }

                    const isPasswordValid = await bcrypt.compare(credentials.password, user.password);

                    if (!isPasswordValid) {
                        return null;
                    }

                    return user;
                }
            })
        ] as Provider[],
        callbacks: {
            async signIn({ user, credentials }) {
                // Check if this sign in callback is being called in the credentials authentication flow.
                // If so, use the next - auth adapter to create a session entry in the database
                // (SignIn is called after authorize so we can safely assume the user is valid and already authenticated).
                if (credentials &amp;amp;&amp;amp; credentials.username &amp;amp;&amp;amp; credentials.password) {
                    if (user) {
                        const sessionToken = crypto.randomUUID();
                        // Set expiry to 30 days
                        const sessionExpiry = new Date(Date.now() + 60 * 60 * 24 * 30 * 1000);

                        await PrismaAdapter(prisma).createSession({
                            sessionToken: sessionToken,
                            userId: user.id,
                            expires: sessionExpiry
                        });

                        event.cookies.set('next-auth.session-token', sessionToken, {
                            expires: sessionExpiry
                        });
                    }
                }

                return true;
            }
        },
        jwt: {
            // Add a callback to the encode method to return the session token from a cookie
            // when in the credentials provider callback flow.
            encode: async (params) =&amp;gt; {
                if (
                    event.url.pathname?.includes('callback') &amp;amp;&amp;amp;
                    event.url.pathname?.includes('credentials') &amp;amp;&amp;amp;
                    event.request.method === 'POST'
                ) {
                    // Get the session token cookie
                    const cookie = event.cookies.get('next-auth.session-token');

                    // Return the cookie value, or an empty string if it is not defined
                    return cookie ?? '';
                }
                // Revert to default behaviour when not in the credentials provider callback flow
                return encode(params);
            },
            decode: async (params) =&amp;gt; {
                if (
                    event.url.pathname?.includes('callback') &amp;amp;&amp;amp;
                    event.url.pathname?.includes('credentials') &amp;amp;&amp;amp;
                    event.request.method === 'POST'
                ) {
                    return null;
                }

                // Revert to default behaviour when not in the credentials provider callback flow
                return decode(params);
            }
        },
        session: {
            strategy: 'database',
            maxAge: 60 * 60 * 24 * 30, // 30 days
            updateAge: 60 * 60 * 24, // 24 hours
            generateSessionToken: () =&amp;gt; {
                return crypto.randomUUID();
            }
        }
    })({
        event,
        resolve
    });

    return result;
};

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Signing up users
&lt;/h2&gt;

&lt;p&gt;Creating a user account is quick and effortless when you use Prisma. With just a few lines of code, you can add new users to your database and get them started in no time. Take a look at the code below:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;const user = await prisma.user.create({
    data: {
        username: username,
        password: await bcrypt.hash(password, 10)
    }
});

const account = await prisma.account.create({
    data: {
        userId: user.id,
        type: 'credentials',
        provider: 'credentials',
        providerAccountId: user.id
    }
});
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



</description>
      <category>cryptocurrency</category>
      <category>crypto</category>
      <category>blockchain</category>
      <category>web3</category>
    </item>
  </channel>
</rss>
