# suno.ai

## Route redirection via Cloudflare

This app is deployed to about.suno.com through Vercel, and then a Cloudflare worker and worker reverse proxy's the content under the suno.com/about and suno.com/blog.

Worker page for about:
- https://dash.cloudflare.com/615cf0d9c11d51b00799dde2abce178f/workers/services/view/suno-ai--to-suno-com-about/production

Worker page for blog:
- https://dash.cloudflare.com/615cf0d9c11d51b00799dde2abce178f/workers/services/view/suno-ai--to-suno-com-about/production

Route handling for both:
- https://dash.cloudflare.com/615cf0d9c11d51b00799dde2abce178f/suno.com/workers


## Features

- **Framework**: Next.js (Pages Router) + TypeScript
- **Styling**: Sass/CSS Modules and PostCSS
- **Animation**: Framer Motion
- **Markdown/MDX**: next-mdx-remote and gray-matter
- **Linting**: ESLint
- **Formatting**: Prettier
- **Git hooks**: Husky, lint-staged, and commitlint
- **Sitemap generation**: next-sitemap

## Requirements

- [Node.js](https://nodejs.org)
- A Node version manager like [nvm](https://github.com/nvm-sh/nvm) or a runtime version manager like [mise](https://github.com/jdx/mise)

## Getting started

Install and switch to the Node.js version specified in `.nvmrc` using your version manager of choice.

> [!IMPORTANT]  
> Since v16.13, installations of Node.js are distributed with [Corepack](https://github.com/nodejs/corepack) by default for managing package managers.
> However, due to its experimental status, Corepack currently needs to be explicitly enabled before usage:
>
> ```sh
> corepack enable
> ```
>
> For alternative methods to install pnpm, [see here](https://pnpm.io/installation).

Install the dependencies:

```sh
pnpm install
```

Start the development server:

```sh
pnpm dev
```

Generate an optimized production build and start the compiled application in production mode:

```sh
pnpm build
pnpm start
```

## Environment variables

While working locally, you can override the defaults set in `.env.development` by creating `.env`.

- `ENV`: Can be set to `development`, `staging` or `production`, and is used to determine which feature flags are enabled in which environment.
- `ENABLE_DRAFTS`: Set to `true` to override the draft frontmatter field on all content entities in order to allow previewing draft content.
- `NEXT_PUBLIC_ENABLE_DEBUG`: Controls the visibility of debug-related views and controls, which can be accessed via the `?debug` query parameter.

## Architecture

```
.
├── content/
│   ├── sections/
│   │   ├── about.mdx
│   │   └── team.mdx
│   ├── privacy.mdx
│   └── terms.mdx
├── public/
├── scripts/
│   └── feature-flags.js
└── src/
    ├── assets/
    ├── components/
    ├── config/
    ├── helpers/
    ├── hooks/
    ├── lib/
    │   ├── api.ts
    │   └── mdx-api.ts
    ├── pages/
    │   ├── [slug].tsx
    │   └── index.tsx
    ├── store/
    ├── styles/
    │   └── export/
    └── types/
        └── global.d.ts
```

### `📁 content/`

Content files are located within the `content/` directory, and can be either standard Markdown files with the `.md` extension, or MDX files with the `.mdx` extension.
Markdown/MDX files can be used to create two types of content entities:`MDXPage` and `MDXSection`.

- `MDXPage`: Top-level Markdown/MDX files are rendered as dynamic pages. Example: `content/terms.mdx`.
- `MDXSection`: Markdown/MDX files defined within the `content/sections/` directory represent content that is to be rendered within individual `<Section />` components on the homepage. Example: `content/sections/about.mdx`.

#### [Frontmatter](https://mdxjs.com/guides/frontmatter/)

Note that all frontmatter fields are currently optional.

`MDXPage` supports the following frontmatter:

- `slug`: The slug for the generated page. If unset, the file name will be used for the page slug.
- `title`: The title of the generated page, which will be set in the meta tags.
- `description`: A description for the generated page, which will be set in the meta tags.
- `layout`: Can be either `primary` or `secondary`. The content of primary pages is rendered within the base-level `RootLayout` component, whereas secondary pages are additionally wrapped in the `NestedLayout` component, which includes more extensive styling ideal for text-heavy content pages, such as a blog post or article, the Terms & Conditions page, etc.

`MDXSection` supports the following frontmatter:

- `title`: The title for the generated section, which will be rendered as a heading.
- `order`: Determines the position of the section on the homepage, sorted in ascending order. If unset, the section will be placed after all ordered sections.

Both `MDXPage` and `MDXSection` support the following frontmatter:

- `draft`: Boolean. If set to `true`, it will determine whether or not the content entity should be published on the site.
- `theme`: Can be either `light` or `dark`. If set, it will determine the global site theme.

#### Drafts

A `MDXPage` file with `draft: true` in its frontmatter means that the page will not be built and the route will direct to the 404 page instead.
The `ENABLE_DRAFTS` environment variable can be used to override the `draft` field on all content entities in order to allow previewing draft content.

Example: `content/kitchen-sink.mdx`. By setting `ENABLE_DRAFTS=true` locally or in select non-production deploys, this unpublished page can be useful for testing standalone components, rendering their different variants, and previewing typography styles — kind of like a simplified, one-page Storybook.

### `📁 scripts/`

- `feature-flags.js`: Defines feature flags for each environment, which is determined by the ENV environment variable:
- `dynamic-config-webpack-plugin.js`: A small custom Webpack plugin that wraps `webpack.DefinePlugin` and generates the global type declarations file, which is by default `src/types/global.d.ts`.

Note that unlike conventional feature flags which allow for toggling values at runtime, the current implementation approach uses Webpack to substitute the above feature flags for the boolean literals they evaluate to at compile time.

### `📁 src/`

- `lib/`
  - `mdx-api.ts`: Responsible for fetching, processing, and serializing the MDX content located in the `content/` directory.
  - `api.ts`: A thin layer of abstraction over the MDX-specific logic, providing a higher-level API for use in the application.
