Huge News!Announcing our $40M Series B led by Abstract Ventures.Learn More
Socket
Sign inDemoInstall
Socket

next-ssr-form

Package Overview
Dependencies
Maintainers
1
Versions
18
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

next-ssr-form

> **⚠️⚠️ This is an experimental library and is likely to be discontinued ⚠️⚠️**

  • 1.0.4
  • latest
  • npm
  • Socket score

Version published
Weekly downloads
1
Maintainers
1
Weekly downloads
 
Created
Source

next-ssr-form

⚠️⚠️ This is an experimental library and is likely to be discontinued ⚠️⚠️

About

  • 🔨 Uses Next.js' getServerSideProps to receive post data and provide helpers to the page to render the form
  • 🎷 E2E type safety! TypeScript types inferred between client & server with all the nice autocomplete jazz
  • 🔐 Server-side data validation that's propagated to page props & your mutations' return values are inferred.
  • ☁️ Allows you to write data straight to the db with confidence
  • 🤘 Your page will wors without JS enabled (if you want it to)

(Peer) Dependencies:

  • zod for data validation
  • Formik as the form library

Table of contents:

Get started

ℹ️ Easiest thing to do is to look at the pages in examples/typescript.

0. Install

yarn add next-ssr-form zod formik

1. Add form to top of page

In a Next.js page/..:

export const createPostForm = createForm({
  schema: z.object({
    from: z.string().min(2),
    message: z.string().min(4),
  }),
  defaultValues: {
    message: "",
    from: "",
  },
  formId: "createPost",
});

2. Add mutation to getServerSideProps

export const getServerSideProps = async (ctx: GetServerSidePropsContext) => {
  const createPostProps = await createPostForm.getPageProps({
    ctx,
    /**
     * Your mutation function
     * - Will only be called when there's a POST to this form based on the `formId`
     * - 🌟 The `input` will be validated by the schema & the types inferred!
     */
    async mutation(input) {
      return DB.createPost(input);
    },
  });

  return {
    props: {
      // spread properties onto the prop
      ...createPostProps,
      posts: await DB.getAllPosts(),
    },
  };
};

3. Infer data types

type Props = InferGetServerSidePropsType<typeof getServerSideProps>;

export default function Home(props: Props) {
  // ...

Your data usage is now typesafe!

4. Use form

Basic form w/o JS

type Props = InferGetServerSidePropsType<typeof getServerSideProps>;
export default function Home(props: Props) {
  const [feedback, setFeedback] = useState(
    createPostForm.getFeedbackFromProps(props)
  );
  const initalValues = createPostForm.getInitialValues(props);
  const initialErrors = createPostForm.getInitialErrors(props);

  return (
    <>
      <h1>Normal http post (zod for validation)</h1>
      <p>
        Uses a standard <code>&lt;form&gt;</code> with the <code>action</code>
        -attribute to post to the same page. Form data is handled in{' '}
        <code>getServerSideProps</code> and feedback is passed through page
        props.
      </p>
      <h2>My guestbook</h2>
      {props.posts.map(item => (
        <article key={item.id}>
          <strong>
            From {item.from} at {item.createdAt}:
          </strong>
          <p className="message">{item.message}</p>
        </article>
      ))}
      <h3>Add post</h3>

      <form action={props.createPost.endpoints.action} method="post">
        <p className={`field ${initialErrors?.from ? 'field--error' : ''}`}>
          <label>
            Your name:
            <br />
            <input type="text" name="from" defaultValue={initalValues.from} />
            {initialErrors?.from && (
              <span className="field__error">{initialErrors.from}</span>
            )}
          </label>
        </p>
        <p className={`field ${initialErrors?.message ? 'field--error' : ''}`}>
          <label>
            Your message:
            <br />
            <textarea name="message" defaultValue={initalValues.message} />
            {initialErrors?.message && (
              <span className="field__error">{initialErrors.message}</span>
            )}
          </label>
        </p>
        <input type="submit" />

        <br />
        {feedback?.state === 'success' && (
          <span className="feedback success">Yay! Your entry was added</span>
        )}

        {feedback?.state === 'error' && (
          <>
            <span className="feedback error">
              Something went wrong: {feedback.error.message}. Full Error:{' '}
              <pre>
                {JSON.stringify(
                  {
                    ...feedback.error,
                    message: feedback.error.message,
                    stack: feedback.error.stack,
                  },
                  null,
                  4
                )}
              </pre>
            </span>
          </>
        )}
      </form>
    </>
  );
}

Author

@alexdotjs

FAQs

Package last updated on 04 Jan 2021

Did you know?

Socket

Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.

Install

Related posts

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc