---
title: Development setup and commands to build, serve, and more
linkTitle: Dev setup and more
description: Learn how to set up a development environment for this website.
what-next: >
  You're now ready to [build](#build), [serve](#serve), and make updates to
  website files. For details on how to submit changes, see [Submitting
  content](../pull-requests).
weight: 60
cSpell:ignore: TOCSS
---

> [!WARNING] Supported build environments
>
> Builds are officially supported on Linux-based environments and macOS. Other
> environments, such as [DevContainers](#devcontainers), are supported on a
> best-effort basis. For builds on Windows, you can follow steps similar to
> those for Linux using Windows Subsystem for Linux command line [WSL][].

The following instructions explain how to set up a development environment for
this website.

## Cloud-IDE setup

### Gitpod

To work via [Gitpod.io][]:

1.  Fork this repository. For help, see [Fork a repository][fork].
2.  From [gitpod.io/workspaces][], create a new workspace (do this only once) or
    open an existing workspace over your fork. You can also visit a link of the
    form:
    `https://gitpod.io#https://github.com/YOUR_GITHUB_ID/opentelemetry.io`.

    > **Note**: If you have the necessary permissions to work from this
    > repository, or just want to look around, open
    > <https://gitpod.io/#https://github.com/open-telemetry/opentelemetry.io>.

Gitpod automatically installs the repo-specific packages for you.
{{% param what-next %}}

### Codespaces

To work via GitHub [Codespaces][]:

1. [Fork][] the website repository.
2. Open a Codespace from your fork.

Your development environment will be initialized via the
[DevContainer](#devcontainers) configuration. {{% param what-next %}}

## Local setup

1.  [Fork][] and then [clone][] the website repository at
    <{{% param github_repo %}}>.
2.  Go to the repository directory:

    ```sh
    cd opentelemetry.io
    ```

3.  Install or upgrade to the [**active LTS** release][nodejs-rel] of Node.js.
    We recommend using [nvm][] to manage your Node installation. Under Linux,
    run the following command, which will install and upgrade to the version
    specified in the .nvmrc file:

    ```sh
    nvm install
    ```

    To [install under Windows][nodejs-win], use [nvm-windows][]. We recommend
    using `cmd` and not Windows PowerShell for the command below:

    ```cmd
    nvm install lts && nvm use lts
    ```

4.  Get npm packages and other prerequisites:

    ```sh
    npm install
    ```

    Or, for the [lock-exact, script-suppressing setup][ci-install] that CI and
    the devcontainer use:

    ```sh
    npm run install:safe
    ```

    Either install uses the dependency versions pinned in the committed
    `package-lock.json`. Lock-file cases:

    - **You changed dependencies**: regenerate the lock file and commit it
      together with `package.json`:

      ```sh
      npm install --package-lock-only --ignore-scripts
      ```

    - **Merge conflict on the lock file**: take the `main` version and rerun the
      command above.
    - **The lock file changed, but you didn't change dependencies** (a
      `postinstall` check warns when an install does this): that signals drift;
      restore the lock and investigate rather than committing the rewrite.

    Site maintainers own [other lock-file maintenance][ci-install].

Launch your favorite IDE. {{% param what-next %}}

### Build

To build the site run:

```sh
npm run build
```

The generated site files are under `public`.

> [!IMPORTANT]
>
> If you see build or serve command **errors** similar to the following:
>
> ```log
> ERROR error building site: ...[long message]... TOCSS: failed to transform "/scss/main.scss" (text/x-scss)
> ```
>
> Or:
>
> ```log
> ERROR failed to load modules: module "github.com/FortAwesome/Font-Awesome" not found
> ```
>
> This is usually because you didn't complete all the steps in the
> [local setup](#local-setup). In particular, (re)run this command:
>
> ```sh
> npm install
> ```

### Serve

To serve the site run:

```sh
npm run serve
```

The site is served at [localhost:1313][].

If you need to test [Netlify][] redirects, use the following command and visit
the site at [localhost:8888][]:

```sh
npm run serve:netlify
```

The serve command serves files from memory, not from disk.

If you see an error like `too many open files` or `pipe failed` under macOS, you
might need to increase the file descriptor limit. See
[Hugo issue #6109](https://github.com/gohugoio/hugo/issues/6109).

### Content and submodules

The website is built from the following content:

- Files under `content/`, `static/`, etc. per [Hugo][] defaults.
- Mount points, defined by Hugo [config][] in
  `config/_default/module-template.yaml`. Mounts are either directly from git
  submodules under [content-modules][], or preprocessed content from
  `content-modules` (placed under `tmp/`), and no where else.

[config]: https://github.com/open-telemetry/opentelemetry.io/tree/main/config
[content-modules]:
  https://github.com/open-telemetry/opentelemetry.io/tree/main/content-modules

### Submodule changes

If you change any content inside of a [content-modules][] submodule, then you
need to first submit a PR (containing the submodule changes) to the submodule's
repository. Only after the submodule PR has been accepted, can you update the
submodule and have the changes appear in this website.

It's easiest to manage your `content-modules` changes by working with the
repository that the corresponding submodule is linked to, rather than inside the
submodule itself.

Expert contributors can work directly in the submodule. You are then able to
directly build and serve your (submodule) changes. By default, the CI scripts
get submodules on every invocation. To prevent this behavior while you work
within a submodule, set the environment variable `GET=no`. You also need to run
`git fetch --unshallow` the submodule before you can submit a PR. Alternatively,
set `DEPTH=100` and re-fetch submodules.

## DevContainer support {#devcontainers}

This repository is configured for use in [Development
Containers][devcontainers], which are supported by various cloud and local IDEs
such as (in alphabetical order):

- [Codespaces][cs-devc]
- [DevPod](https://devpod.sh/docs/developing-in-workspaces/devcontainer-json)
- [Gitpod](https://ona.com/docs/ona/configuration/devcontainer/overview)
- [VSCode](https://code.visualstudio.com/docs/devcontainers/containers#_installation)

## Tools

### Code-excerpter

Use [code-excerpter][] for code snippets that should stay in sync with source
files in this repository. Site pages in any locale can contain code excerpts,
but original content that uses them is authored in English under `content/en`
and then updated by localization teams to their own locales.

In the English source page, place a file excerpt directive immediately before
the fenced code block that it updates:

````md
<?code-excerpt path-base="examples/java/getting-started"?>

<?code-excerpt "src/main/java/otel/DiceApplication.java" from="@SpringBootApplication"?>

```java
@SpringBootApplication
public class DiceApplication {
  public static void main(String[] args) {
    SpringApplication app = new SpringApplication(DiceApplication.class);
    app.setBannerMode(Banner.Mode.OFF);
    app.run(args);
  }
}
```
````

Use an optional `path-base` directive once near the top of the page when several
excerpts come from the same directory. For details concerning the `code-excerpt`
directive syntax, see the [code-excerpter][] readme.

Edit the source file or the directive, **not the fenced code**. Then run the
following [npm script](/site/build/npm-scripts/):

```sh
npm run fix:code-excerpts
```

To check is code-excerpts are up to date, run:

```sh
npm run check:code-excerpts
```

[code-excerpter]: https://github.com/chalin/code-excerpter

<!-- prettier-ignore-start -->
[ci-install]: /site/build/ci-workflows/#dependency-installation
[clone]: https://docs.github.com/en/repositories/creating-and-managing-repositories/cloning-a-repository
[codespaces]: https://docs.github.com/en/codespaces
[cs-devc]: https://docs.github.com/en/codespaces/setting-up-your-project-for-codespaces/adding-a-dev-container-configuration/introduction-to-dev-containers#about-dev-containers
[devcontainers]: https://containers.dev/
[fork]: https://docs.github.com/en/get-started/quickstart/fork-a-repo
[gitpod.io]: https://gitpod.io
[gitpod.io/workspaces]: https://gitpod.io/workspaces
[hugo]: https://gohugo.io
[localhost:1313]: http://localhost:1313
[localhost:8888]: http://localhost:8888
[netlify]: https://netlify.com
[nodejs-rel]: https://nodejs.org/en/about/previous-releases
[nodejs-win]: https://docs.microsoft.com/en-us/windows/dev-environment/javascript/nodejs-on-windows
[nvm-windows]: https://github.com/coreybutler/nvm-windows
[nvm]: https://github.com/nvm-sh/nvm/blob/master/README.md#installing-and-updating
[WSL]: https://learn.microsoft.com/en-us/windows/wsl/install
<!-- prettier-ignore-end -->
