npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2024 – Pkg Stats / Ryan Hefner

next-server-state

v1.0.3

Published

A package that provides shared state management between Server and Client components in Next.JS v13 app router

Downloads

7

Readme

Next-Server-State

:warning: This package is an experimental project to test and create the best approach for seamlessly sharing state between Server and Client components in Next.js app router. Contributions and suggestions are welcome :pray: .

This package provides shared state between server and client components in Next.js App router. It utilizes server-side session storage to store the state, seamlessly synchronizing it across components. Additionally, it offers a easy approach for reading and writing state data from both server and client sides.

Demo: https://next-server-state.vercel.app/

Setup

Install package:

npm i next-server-state

Setup dynamic route:

Create file with path: /pages/api/server-state/[...path].ts (or .js if youre not using typescript)

/pages/api/server-state/[...path].ts
import { setupServerStateRoutes } from 'next-server-state';

export default setupServerStateRoutes();
Setup your server state:

// /lib/my-server-state.ts
import {
  createServerState,
  getServerState,
  useServerState
} from 'next-server-state';

type MyServerStateProps = {
  first_name: string;
  last_name: string;
  counter: number;
};

export const MyServerState =
  createServerState<MyServerStateProps>('my-state-unique-key', {
    first_name: '',
    last_name: '',
    counter: ''
  });

export function useMyServerState() {
  return useServerState<MyServerStateProps>(MyServerState);
}
export async function getMyServerState() {
  return getServerState<MyServerStateProps>(ExampleOneServerState);
}

Setup state context:

Wrap your server and client component of which you wish to consume the server state in

import { MyServerState } from '../lib/my-server-state.ts'; // import state variable from the file you initialised it in

export const MyParentComponent = () => {
    return (
        <MyServerState.Provider>
            // ...your server and client components go here
        </MyServerState.Provider>
    )
}

Usage

How you use the server state depends on whether you're using it on server side or client side:

  • Client Components
const [state, updateState] = useServerSide(myServerState)
  • Server Components + Server Actions + Route Handlers
const [state, updateState] = getServerSide(myServerState)

Notice: Using getServerSide on client side will result in an error, and same goes with using useServerSide on the server side. so make sure you use the corosponding functions correctly.

Usage cases

Client Component you can read and set state data like so:

'use client'
import { useMyServerState } from '../lib/my-server-state.ts'; // import from the file you initialised the server state in

export function MyClientComponent(){
    const [state, updateState] = useMyServerState();
    
    const handleIncrement = ()=>{
		updateState({
		    counter: Number(state.counter) + 1
		})
    }
    
    return (
        <div>
            <p>Counter: <span>{state.counter}</span></p>
            <button type="button" onClick={handleIncrement}>Increment</button>
        </div>
    )
}

Server Component you can read state and render it like so:

import { getMyServerState } from '../lib/my-server-state.ts'; // import from the file you initialised the server state in

export async function MyServerComponent(){
    const [state, updateState] = await getMyServerState();
    
    // If needed although not recommended, You can also update state on a server component render 
    // await updateState({ first_name: 'new name' })
    // const [newState] = await getServerState();
    
    return (
        <span>
            <span>{state.first_name}</span>
            // ...
        </span>
    )
}

Client Component with Server Actions you can read and set state data like so:

// server-actions.ts
'use server'
import { getMyServerState } from '../lib/my-server-state.ts'; // import from the file you initialised the server state in

export async function actionIncrementCounter(formData: FormData) {
  const [state, updateState] = await getMyServerState();

  updateState({
    counter: Number(state.counter ?? 0) + 1
  });

  return { message: 'Updated' };
}
// MyClientComponent.ts
'use client'
import { useMyServerState } from '../lib/my-server-state.ts'; // import from the file you initialised the server state in
import { actionIncrementCounter } from './server-actions.ts'; // Your server actions

export function MyClientComponent(){
    const [state] = useMyServerState();
    
    return (
        <div>
            <p>Counter: <span>{state.counter}</span></p>
            <form action={actionIncrementCounter}>
                <button type="submit">Increment</button>
            </form>
        </div>
    )
}

App Route Handler you can read and set state data like so:

import { getMyServerState } from '../lib/my-server-state.ts'; // import from the file you initialised the server state in

export async function POST() {
    const [state, updateState] = await getMyServerState();
    
    updateState({
        counter: Number(state.counter) + 1
    })
    
    return { message: 'Counter incremented' };
}