feature: it's user interactions that store, update and manipulate data. It processes the data from UI to database to store it, and it extracts some data from database and process them to transfer them to the users.
component does nothing about this, it's just about navigation. so I'll put them just right there.
changing color animation
layout: client component renders server components(or client components) as props.
Building progress animation
- changing color on button click: impossible since we cannot transfer props to the children. If we change them to client components, we're bound to give up all the performance benefits since all the rendered components become client components.
- changing the color on pathname
AutoAnimate
new update: AutoAnimate juggles elements when you use the same values for the array. Since it just works, I can create an array based on the current pathname
.
font optimization in client components
Link component
Using Link optimizes the performance by prefetching the route. That is why they recommend using <Link />
components rather than useRouter()
hook.
Enum to array
you can extract the values of enum using Object.values(Enum)
.
Setting up Zustand
- global store shouldn't be used anymore; Multiple requests have their store using contexts instead of persisting them as a module state.
- Both Server components render and Client components render. Since their outputs are different(
store
is set to default values in server components, hydration errors are thrown(local data storage, local fetch). By initializing the Store in SSR, it can keep
Should I use Form elements?
- If you get data across multiple pages and only send data to the server on the last page. In this situation, is it recommended to use form elements for each page?
- There is no standard saying that form elements must include control elements and a submit button.
- w3.org actually says it's even better to split a long form into smaller pieces. Therefore, it looks like it's a good practice to use form elements across multiple pages.
Why @vis.gl/react-google-maps
?
- Can draw on the map
- Still being maintained by the community
- Only 3 bugs discovered
- Use hook to be in sync with the google maps state
Environment variables
Next.js will load environment variables from .env.local
file.
- If the name of an environment variable doesn't start with
NEXT_PUBLIC
, it is only accessible on the server. That means if a client component attempts to access it, it'll beundefined
. Therefore, the rendered result would be different from the server and there might be a hydration error. - If the name of environment variable starts with
NEXT_PUBLIC
, Next.js replaces all theprocess.env.[variable]
with the given value. That's why client components can also access environment variables.
.refine
When you need to customize with your own rules, you can use .refine()
method.
some methods take errorMap instead of errorMessage itself.
const getEnvVariable = (key: string) => {
console.log(key); // "BASE_URL"
console.log(process.env[key]); // undefined
console.log(process.env["BASE_URL"]); // http://localhost:3000
if (process.env[key] === undefined) {
throw new Error(`Environment variable is undefined`);
}
return process.env[key];
};
Why??
MSW Troubleshooting
Hot Module Reloading problems caused by Next.js Architecture
If you're using next.js, you must run msw
on the client and server side. The problem comes into play when you change the handler
of MSW. Next.js will not refresh on handler updates. Here's why.
Next.js 14 manages two processes. One is a long-term process and it's used for updating RootLayout. The other one is a short-term process used for updating relatively small routes. Since MSW is registered as a global module, the long-term process manages MSW. However, processes don't share memory. Therefore, Next.js doesn't refresh the short-term process.
Strategic Decision
I still decided to use MSW for mocking APIs because Hot Module Reloading is not a serious problem. Since I'll develop each component using Storybook in isolation, the dev server doesn't need fresh updates. So I'll keep using MSW to see the result in the dev server when all the components get together.
Instrumention
If you want to run some code every time Next.js starts running, you can register()
it. This feature is typically used for integrating Next.js and logging/monitoring tools.
Cannot find module msw/node
You should set up next.config.js to enable instrumentation.
module.exports = {
experimental: {
instrumentationHook: true,
}
}
However, I got "Cannot find module msw/node" error even though I set it up with the option. The doc says 'Place the file in the root of your application or inside an src folder if using on'. I followed the Feature-Sliced Design's convention, which looks like the following image.
When I set up Next.js initially, I chose the root directory option, so I thought "Cannot find module 'msw/node'" was thrown, and after many trials and errors, I found out I should have placed the file in the /src
directory.
Cannot find module msw/browser
To make the example code more tidy, I refactored it with 'early return' approach.
export async function enableMocking() {
// early return doesn't work
if (
typeof window === "undefined" ||
process.env.NODE_ENV !== "development"
) {
return;
}
const { worker } = await import("@/mocks/browser");
await worker.start();
}
It kept throwing Cannot find module msw/browser
. I attempted to change the path of the dynamic import to the relative one without using the path alias and set up package.json. However, it came down to this early return pattern. If I avoid this approach, my app runs with the error on the client side.
// Next.js picks up instrumentation.ts file in /src directory
export async function enableMocking() {
// early return doesn't work
if (
typeof window !== "undefined" &&
process.env.NODE_ENV === "development"
) {
const { worker } = await
import("@/mocks/browser");
await worker.start();
}
}
As a side note: I had the same problem with the server-side configuration. If you know something about this problem, please let me know.