# suno.ai

## 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/en/)
- [pnpm](https://pnpm.io/)
- A Node Version Manager like [nvm](https://github.com/nvm-sh/nvm) or [fnm](https://github.com/Schniz/fnm)

## Getting started

Switch to the Node.js version specified in the `.nvmrc`:

```sh
nvm use
# or
fnm use
```

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.development.local` or `.env.local`.

- `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.

## Config

In `src/config/constants` you can manage the SUNO promotion tag that is sended to the generate endpoint.

- `SUNO_PROMOTION = "vday"`

## Architecture

```
.
├── content/
│   ├── 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`.

#### [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`.
- `copy/parseCopy.js`: A small script to retrieve and parse the copy coming from a [Google Spreadsheet](https://docs.google.com/spreadsheets/d/1KoYd_iT2ZqYAw8Ty0EM_ai9xtjjGbNwTRGoWsUp7nBI/edit#gid=1178312769).

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.
