React/Next.js Frontend for theworld.org. A daily world news public media program.
Make sure you have node, NPM, yarn, and now installed and/or updated. Tested and required versions:
node
20.0.0+ - Node.js® is a JavaScript runtime built on Chrome's V8 JavaScript engine.npm
10.0.0+ - CLI used to manage node pages.yarn
1.22.0+ - Wrapper CLI for npm that streamlines package retrieval and management.
It is recommended to install and update using asdf. Follow Getting Started guide for installation instructions.
Once asdf has been installed, use it to install the configured version of node and npm by running the following command in your terminal:
asdf install
To install yarn, follow their Installation instructions for your OS. Install the Stable version.
Now we are ready to clone this repo and get its packages installed and initialized. The following will create a PRX
directory in your home directory and clone the repo into ~/PRX/theworld.org
:
cd ~
mkdir PRX
cd PRX
git clone [email protected]:PRX/theworld.org.git
cd theworld.org
By default, development environments will pull API data from the dev staging environment. To pull data from the live API, in the
./config
directory, make a copy ofproduction.json
and rename it tolocal.json
.
Now we need to make sure we are using the the version of node need for the app:
nvm use
Now lets install all the packages required by the app:
yarn
Next we need to setup the environment variables:
cp .env.example .env.local
Update variable values as needed. Some features, like newsletter subscriptions will not work until a valid key is provided here.
Finally, lets spin up the development server:
yarn dev:start
Then open the app in your browser at localhost:3000.
When you have your local Lando WordPress environment running, and need to develop features that require WordPress authentication cookies, you can use the-world-wp.lndo.site:3000.
Yes, We are using typescript. This will require some extra steps to provide explicit types or interfaces for class components, and function parameters and return values. Types and interfaces specific to a component can be exported from the component file. Types and interfaces used by more than one component should be defined in ./interfaces
and organized into its own modeule directory. Module directories should include a index.ts
that exports the exported entities from that modules interface files. An export should also be added to ./interfaces.index.ts
for the module.
It is highly recommended to use an IDE that either supports typescript or has a plugin for typescript. Visual Studio Code is the preffered IDE at this time as project specific settings are provided for it for linting and formatting for javascript and typescript.
When importing module exports, do not use relative import paths for exports not local to the importing module. For example, when importing a function from ./lib
in your component in ./components/MyComponent
, use import myFunction from '@lib/myFunction';
instead of import myFunction from '../../lib/myFunction';
@components
-> ./components
@contexts
-> ./contexts
@interfaces
-> ./interfaces
@lib
-> ./lib
@store
-> './store'
@svg
-> ./assets/svg
@theme
-> ./theme
Additional aliases must be defined all of the following:
./tsconfig.json
./jsconfig.json
./next.config.js
./jest.config.js
Component files should be organized in a module directory in ./components
. The module should include at least the component file and an index file. The component file should export the component as a named export.
Exception NextJS expects a default export page components in
./pages
. Append// eslint-disable-line import/no-default-export
to to the export line to make file pass linting.
./components/MyComponent/MyComponent.tsx
export const MyComponent = () => {
return <h1>Hello World</h1>;
};
./components/MyComponent/index.ts
export * from './MyComponent';
./components/OtherComponent/OtherComponent.tsx
import { MyComponent } from '@components/MyComponent';
export const OtherComponent = () => {
return <MyComponent />;
};
Component files can include additional exports. Those exports should also be exported from the index file.
./components/MyComponent/MyComponent.tsx
export interface MyComponentProps {
title: string;
}
export const MyComponent = ({ title }: MyComponentProps) => {
return <h1>{title}</h1>;
};
./components/MyComponent/index.ts
export * from './MyComponent';
./components/OtherComponent/OtherComponent.tsx
import { MyComponent, type MyComponentProps } from '@components/MyComponent';
export const OtherComponent = () => {
const props: MyComponentProps = {
title: 'Hello World'
};
return <MyComponent {...props} />;
};
Component modules can have submodule directories. Submodules directories should follow the same export pattern. Submodule components should only be exported from the index file if they are intended to be used along with the main module component.
Type and interface exports for the main component and submodule components, and any functions or other variables needed for unit tests, should always by exported by the index file.
Application state and data can be passed to components via Contexts. Components can export their own local contexts. Contexts used by the application or by multiple components should be defined in ./contexts
.
This project uses Material UI as the building blocks for components. When creating a coomponent, first review Material UI Components for something with similar behavior. From there use that components API to customize and theme.
Application level theming can be found in ./theme
. See Material UI Theming.
When using a Material UI component not yet used in the application, customize theming of the component at the application level. Component specific theming for addition usage can then be done with a component theme.
Component styling should be done using the Hook API for elements that are not Material UI components.
The process around contributing to this codebase and the workflow by which code changes are proposed and accepted into this project are documented here.