Components go into the components
folder, and pages go into the pages
folder.
If a component is a base component that is commonly used, (like a button with custom styling), please place it in the component
folder, and prefix it's name with Base
(Like BaseButton.tsx
, BaseInput.tsx
, etc.)
If a component is page specific, please place it in the component
folder, and prefix it with the name of a page (like HomeButton.tsx
)
Please do not nest create/nest more folders in the components
folder.
Abstract things reactively, instead of proactively.
Abstraction adds another layer of complexity with your code, and makes the codebase harder to understand so we should be VERY careful when and how we do it. If you do not have a clear reason to abstract something DO NOT DO IT.
As a rule of thumb, do not abstract anything in your initial implementation of a feature. Only afterwards, if it makes sense, and you can justify it.
Just moving things around in new components, and "it's a code smell" are not valid reasons for abstraction.
Do feel free to add comments to your pages/components, especially if they are larger. Comments are also very usfeul to break up large pieces of JSX code on a page/component.
- Storyblok
- Also considering Prismic and NetlifyCMS, as alternatives.
We use NextJS in combination with Vercel for easy github integration and deployments. NextJS has too many benefits to count, but the key selling point is that it makes deploying and optimizing your website/app very easy. So we spend less time configuring things, and more time actually coding them.
We heavily rely and recommend these libraries. They are simple to use, look very good out-of-the-box, and are very customizable, if needed.
- React Hook Form - makes handling forms, form states and form validations so much easier.
- Prettier - for code linting.
- Husky - Easy-to-use git hooks. So we can execute the linting process when you commit soemthing.
- Lint Staged - so we only lint the files that are staged for commits.
You should have all of these tools (and TypeScript) set up, and running in the project. Here's a nicely written guide, detailing how to do so.
- Fetch - the native browser implementation is good enough for most of the use cases. It's native to the browser, so there's nothing to install, and it's quite well documented in the provided link.
SWR - if you need client side fetching, and use a REST API.Please prefer Tanstack Query instead.- Tanstack Query (ex React Query) - if you need to handle data fetching on the client side. Tanstack Query also comes in with builtin cache handling, and many other goodies which make data fetching on client side way easier.
- URQL - GraphQL client which is small and easy to use. Short tutorial video on how to set it up with next.
- graphql-code-generator - So you can generate typescript types from your graphql endpoint. Don't forget to set the
maybeValue: T
in yourcodegen.yml
, like here. Otherwise you'll rip your hair out with the typing. Apollo Client- Just use URQL instead. It has all the featres, and more, and is smaller in size.
-
next-i18next - A translation library for NextJS, which references local JSON files for translation. Prefer using this instead of loading the translations through an API call, because the translations are lodade locally, which is faster and has a smaller footprint than making an API call to get all the translations from something like Storyblok Datasources.
Possible bugs:
- If you are deploying to Vercel, and the translations won't load, or only partially load, consider setting the
localePath
variable in thenext-i18next.config.js
file, like outlined in the github docs.
- If you are deploying to Vercel, and the translations won't load, or only partially load, consider setting the
Or at least, before implementing one, please take a look at the following presentation: Should I Use A Carousel?
If you the client is really really insistant on having a carousel, and must have it:
-
Possible bugs:
- If the carousel doesn't render for some reason, try wrapping it in a
div
and giving it a height and width of a 100%.
- If the carousel doesn't render for some reason, try wrapping it in a
We have a custom implementation of the cookie banner on the SailClass project.
You can copy-paste the component, and change the implementation to what you require on your project.
We're not creating a separate library for it, because it needs to be customizable completely, depending on the project style/cookiename/cookie value/what you do based on the cookie value set. You can find a more detailed explanation in the comments of the component, but basically this component just uses the js-cookie library to get/set the cookie in your browser.