Language

SSR & Next.js

Server rendering, hydration, and what 'today' means on a server.

Safe to import anywhere

bikram-sambat-react touches no browser globals when it's imported or rendered: window and document are only used in effects and event handlers. So it renders on a server (renderToString, streaming, static export) like any other component, and hydrates cleanly. The package's test suite renders both components on the server and hydrates them, checking for mismatch warnings.

Next.js App Router

The package's entry file starts with "use client", so you can render the components straight from a Server Component. Next.js treats them as Client Components automatically:

app/page.tsx
// A Server Component: no "use client" needed here.
import { NepaliCalendar, NepaliDatePicker } from "bikram-sambat-react";
 
export default function Page() {
  return (
    <main>
      <NepaliCalendar />
      <NepaliDatePicker aria-label="Date" name="date" clearable />
    </main>
  );
}

Import the stylesheet once, in your root layout:

app/layout.tsx
import "bikram-sambat-react/styles.css";

Props that are functions (onChange, isDateDisabled, renderDay, components) can't be passed from a Server Component, as with any Client Component. Put the state in a small client component of your own:

app/birth-date-field.tsx
"use client";
 
import { useState } from "react";
import { NepaliDatePicker, type BSDate } from "bikram-sambat-react";
 
export function BirthDateField() {
  const [date, setDate] = useState<BSDate>();
  return <NepaliDatePicker aria-label="Date of birth" value={date} onChange={setDate} />;
}
ⓘ

Tip: for a plain form you may not need state at all. <NepaliDatePicker name="dob" /> submits the date as YYYY-MM-DD through a hidden input, so it works from a Server Component with a Server Action or a regular <form action>.

Today, and hydration

"Today" depends on the clock and timezone of whatever renders the page, and a server's usually differ from your visitor's. So by default the calendar doesn't decide today during server rendering:

  • On the server and during hydration, no day is highlighted as today. Server and client markup are identical, so there's no hydration mismatch.
  • Right after hydration, the calendar highlights the device's local date (adToBs(new Date())).
  • Calendars mounted later, like the date picker's popover, know today on their first render.

To render today on the server too, pass it yourself. todayBs() from bikram-sambat-ts gives today in Nepal (UTC+05:45), whatever the server's timezone:

import { todayBs } from "bikram-sambat-ts";
 
<NepaliCalendar today={todayBs()} />;

The calendar then shows exactly that date as today on the server and in the browser.

The first month shown

Without value, defaultMonth or today, the calendar opens on the current month in Nepal (todayBs()), not the device's. A server and a browser rendering at the same moment always agree on it, even in different timezones, so the markup matches. Pass defaultMonth (or value) to choose it yourself.

Other frameworks

Nothing in the package is Next.js-specific. With Vite (client-only), import the stylesheet in your entry file and use the components anywhere. Any SSR setup works the same way as above, since the components don't read browser globals during render.