This project contains the website of Filecoin Foundation, available at fil.org. This site aims to provide comprehensive information and resources about Filecoin's initiatives and contributions to the decentralized web.
This Next.js project is part of a monorepo managed by Turborepo. To get started, refer to the root README for installation and development instructions.
The following commands are specific to the ff-site workspace and should be run from the root of the monorepo.
| Command | Action |
|---|---|
npx turbo filecoin-foundation-site#dev |
Starts the development server |
npx turbo filecoin-foundation-site#build |
Builds the application |
npx turbo filecoin-foundation-site#start |
Starts the production server |
npx turbo filecoin-foundation-site#lint |
Lints the code |
npm i <package> -w 'apps/ff-site' |
Installs a dependency |
This project uses the following open-source technologies:
- Next.js (App Router) for server-side rendering, static site generation, and routing.
- TypeScript for static type checking.
- Tailwind CSS for utility-first CSS styling.
- Zod for data validation.
We use Decap CMS, formerly known as Netlify CMS, for content management, allowing non-technical team members to update website content easily.
Decap CMS is a Git-based content management system, meaning that content is managed just like any other file in our repository, using Git for version control.
All the content managed through Decap CMS is stored in src/app/content/. This directory includes various Markdown files that the CMS edits. Each file represents a different section or page of the website, structured for easy editing and updates.
The Decap CMS setup includes two configuration files:
public/admin/config.yml- This file primarily contains the content and schema metadata under thecollectionssection, but also includes authentication settings under thebackendsection. We use GitHub as the backend for Decap CMS, as explained in further details below.public/admin/index.html- This HTML template enables viewing and editing the content in a web interface. It is what is loaded when you visit/adminin the browser.
Additionally, src/app/_data/cmsConfigSchema.json is a file autogenerated when the server starts, using predev and prebuild commands. It is a JSON representation of the config.yml file.
We use Markdown files for the content of our websites. It allows us to convert human-readable text into HTML.
Each Markdown file typically consists of two parts:
- The header section: Delimited with triple dashes
---, this YAML-formatted section contains metadata about the file, similar to what you would find in HTML<head>tags: title, description, image links, etc. - The body section: Contains the content itself in Markdown format.
Here’s an example:
---
title: Hello
slug: home
---
# Hello world!
Lorem ipsumMetadata is processed using the gray-matter library, transforming it into an object usable within our code to display content in relevant places:
{
data: { title: 'Hello', slug: 'home' },
content: '<h1>Hello world!</h1><p>Lorem ipsum</p>',
}If you only need to update existing content, there is no need to update Decap’s configuration. Modify the markdown file for the content you wish to update. For example, to change the title on the home page:
- Open
src/content/pages/home.md. - Edit the title in the header section.
The website should hot reload and the changes should appear immediately in your local development environment. Once you’re satisfied with the updates, commit your changes via Git.
If you need to add or remove content from a page or a section, like a subtitle on the home page, then Decap CMS must be informed. Hence, you need to update both the Markdown and the configuration file.
- Add the new content in the Markdown file, e.g., a subtitle in the header of
src/content/pages/home.md. - Update
public/admin/config.ymlto reflect this addition under the appropriate section, for example:
# collections -> name: "pages” -> name: "home”
fields:
- *header_config
- name: "subtitle"
label: "Subtitle"
widget: "string"
required: trueThe widget key is important and worth mentioning. Widgets define the content type of each field: String, Number, Boolean, DateTime, File, Relation, etc. The full list of widgets and their purpose can be found in the Decap CMS documentation.
The Relation widget is how we create links between related pieces of content, such as associating a featured post with a blog page. Relations usually rely on slugs, which are unique identifiers, to link content together.
The CMS is accessible at /admin, whether locally or in production.
Our project integrates with GitHub for user authentication and content management in a production environment. This integration allows authorized users to access the CMS and make changes to the website content. The list of authorized users is available in the settings of the GitHub repository. We also use a Cloudflare worker to handle the authentication process.
This setup is only necessary for production. For local development, follow the instructions below.
You can connect Decap CMS to the local Git repository using Decap's local server by running npx decap-server. This will bypass the GitHub authentication and allow you to work with the CMS locally.
Some personal information that we collect is encrypted due to the open source nature of the project. This includes the name and email of ecosystem project owners. We use the CryptoJS.AES library for encryption. The master key to encrypt and decrypt data is stored in the .env file under ENCRYPTION_SECRET_KEY.
---
title: Ecosystem Project
email: encrypted::X4asd...
full-name: encrypted::X4zxc...
---The CMS is able to encrypt and decrypt data thanks to a custom API endpoint located at apps/ff-site/src/app/api/encryption/route.ts. This endpoint is protected by a production-only environment variable called ENCRYPTION_ENDPOINT_ACCESS_KEY. This variable gets injected into the CMS by the apps/ff-site/scripts/injectEncryptionAccessKeyInCMS.js script at build time only on Vercel.
When running the CMS locally, the API key is not injected as injectEncryptionAccessKeyInCMS.js only runs during Vercel builds. Hence, this error message is displayed Could not perform decrypt operation for value: X4asd... for encrypted values.
If you need to view these values in plain text, you can access the CMS in production to see the decrypted information. But if you absolutely need to decrypt values locally, you can call the decrypt function from apps/ff-site/src/app/_utils/encryption.ts and log the result to the console.
// apps/ff-site/src/app/(homepage)/page.tsx
import { decrypt } from "@/app/_utils/encryption"
console.log(decrypt("encrypted::X4asd..."))Alternatively, you can also manually grab the API key from the Vercel dashboard and manually paste it where the %ENCRYPTION_ENDPOINT_ACCESS_KEY% placeholder is in cmsEncryptionWidget.js. Just remember to undo the changes before committing.
To create a new page template, run the following command from the apps/ff-site directory:
npm run generate:page <page-name>
Replace <page-name> with the desired name of the page. This command will generate the following files with boilerplate content:
app/page-name/page.tsxapp/page-name/layout.tsxapp/page-name/utils/generateStructuredData.tsxcypress/e2e/page_name_spec.cy.ts
It will also update paths.ts to include the new page.
We rely on ESLint and Prettier to ensure consistent code formatting.
We encourage contributors to set up their editors to run Prettier on save. For VSCode, you can add the following to your .vscode/settings.json:
"editor.formatOnSave": trueESLint is configured to run on pre-commit via husky. To run it manually, use npx turbo filecoin-foundation-site#lint. This will fix auto-fixable issues.
We use GitHub Actions for Continuous Integration (CI) to automate testing. Every pull request to the main branch must pass all tests and meet our quality standards. Below are the key workflows in our CI process:
- We run end-to-end (E2E) tests with Cypress to ensure pages contain the correct content and metadata.
- We use Percy to compare visual changes between the PR and the production site. It's possible to disable it by adding
[skip percy]to the PR title. - We use markdownlint-cli2 to lint our Markdown files. This is especially helpful for PRs coming from Decap CMS, as the author doesn't have control over the code formatting.
To ensure the highest quality of user experience, we employ Cypress for end-to-end (E2E) testing.
To run Cypress tests on your local machine:
- Ensure the development server is running:
npx turbo filecoin-foundation-site#dev - Open Cypress Test Runner with
npx cypress openfor interactive testing. - Alternatively, run
npx cypress runto execute tests in headless mode directly from the terminal.
Note
The turbo command needs to be run from the root of the monorepo while the cypress command needs to be run from the apps/ff-site directory.
Cypress tests are located in the cypress/integration directory.
This hands-on approach to testing complements our CI/CD pipeline, allowing developers to verify changes locally before committing them. For more information on Cypress and E2E testing strategies, visit Cypress Documentation.
Check out the development guidelines in the root README for more information.
We welcome contributions to the Filecoin Foundation website!
We try to keep each pull request small and focused. If the work requires large file changes, we break it down into smaller pieces as outlined in this article on GitHub Protips from Sarah Vessels.
This project is licensed under the Creative Commons Attribution 4.0 International license.