{"id":39075705,"url":"https://github.com/cloud-gov/pages-redirects","last_synced_at":"2026-01-17T18:26:30.932Z","repository":{"id":19048319,"uuid":"85883038","full_name":"cloud-gov/pages-redirects","owner":"cloud-gov","description":"Redirects traffic from previous pages.18f.gov sites to their new URLs.","archived":false,"fork":false,"pushed_at":"2025-10-02T17:37:27.000Z","size":597,"stargazers_count":3,"open_issues_count":2,"forks_count":25,"subscribers_count":86,"default_branch":"main","last_synced_at":"2025-10-02T19:26:28.923Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":"","language":"JavaScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"other","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/cloud-gov.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":"CONTRIBUTING.md","funding":null,"license":"LICENSE.md","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":"CODEOWNERS","security":"SECURITY.md","support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2017-03-22T22:39:21.000Z","updated_at":"2025-10-02T17:37:29.000Z","dependencies_parsed_at":"2023-11-13T23:25:03.018Z","dependency_job_id":"602cf39e-9354-4bf9-b14c-da17ae0d5bd9","html_url":"https://github.com/cloud-gov/pages-redirects","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/cloud-gov/pages-redirects","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/cloud-gov%2Fpages-redirects","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/cloud-gov%2Fpages-redirects/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/cloud-gov%2Fpages-redirects/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/cloud-gov%2Fpages-redirects/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/cloud-gov","download_url":"https://codeload.github.com/cloud-gov/pages-redirects/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/cloud-gov%2Fpages-redirects/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":28515471,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-01-17T17:57:59.192Z","status":"ssl_error","status_checked_at":"2026-01-17T17:57:52.527Z","response_time":85,"last_error":"SSL_connect returned=1 errno=0 peeraddr=140.82.121.5:443 state=error: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2026-01-17T18:26:30.861Z","updated_at":"2026-01-17T18:26:30.922Z","avatar_url":"https://github.com/cloud-gov.png","language":"JavaScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# pages-redirects\n\n[![CircleCI](https://circleci.com/gh/18F/pages-redirects.svg?style=svg)](https://circleci.com/gh/18F/pages-redirects)\n\nThis app redirects traffic from previous `pages.18f.gov` sites to their new URLs,\nwhich are usually a subdomain of `18f.gov` (eg `pages.18f.gov/boop` → `boop.18f.gov`).\n\nThis app also contains a number of non-pages.18f.gov-related redirects that were\npreviously handled by [pages-redirects](https://github.com/18F/pages-redirects) for TTS in the 18F GitHub organziation. These redirect rules can be found in [`templates/_federalist-redirects.njk`](./templates/_federalist-redirects.njk).\n\n## Adding a new redirect\n\n### pages.18f.gov redirects\nTo add a new redirect from a retired pages.18f.gov to its new 18f.gov-subdomain home,\nyou will need to edit [`pages.yml`](/pages.yml). Please open a [Pull Request](https://github.com/18F/pages-redirects/pull/new/main)\nwith your modifications.\n\nIf you need to add a simple redirect of `pages.18f.gov/site-name` to `site-name.18f.gov`,\nsimply add a new line to the `pages.yml` that looks like:\n\n```yml\n- site-name\n```\n\nIf you need to change the name of the old page to something new, like\n`pages.18f.gov/old-name` to `new-name.18f.gov`,\nadd lines of the following form to `pages.yml`:\n\n```yml\n- from: old-name\n  to: new-name\n```\n\nIf you need to redirect to a _different domain_ from `18f.gov`, like\n`pages.18f.gov/old-name` to `new-name.new-domain.gov`,\nadd lines of the following form to `pages.yml`:\n\n```yml\n- from: old-name\n  to: new-name\n  toDomain: new-domain.gov\n```\n\nAdditionally you can redirect to a _custom path_ on that domain, like\n`pages.18f.gov/old-name` to `new-name.new-domain.gov/custom-path`,\nadd lines of the following form to `pages.yml`:\n\n```yml\n- from: old-name\n  to: new-name\n  toDomain: new-domain.gov\n  toPath: custom-path\n```\n\n### Domain redirects\nTo create a redirect for yourOrigDomain.gov to yourNewDomain.gov, perform the following steps:\n1. Add a route for yourOrigDomain.gov in [`manifest-prod.yml.njk`](/templates/manifest-prod.yml.njk)\n```\nroute: yourOrigDomain.gov\n```\n2. Add a redirect configuration in [`_federalist-redirects.njk`](/templates/_federalist-redirects.njk):\n```\nserver {\n  listen {{ PORT }};\n  set $target_domain yourNewDomain.gov;\n  server_name yourOrigDomain.gov;\n  return 301 https://$target_domain;\n}\n```\n3. Add yourOrigDomain.gov as an external link to [`docker-compose.yml`](/docker-compose.yml)\n```\napp:yourOrigDomain.gov\n```\n4. Test this app as described below in the `Testing` section\n5. Create a pull request in the the [dns repository](https://github.com/18F/dns) to follow the [cloud.gov instructions](https://cloud.gov/docs/services/external-domain-service/#how-to-create-an-instance-of-this-service) to create the required DNS entries for `yourOrigDomain.gov` and ask @cloud-gov/pages-ops for a review.\n6. Ask an administrator to create an [`external-domain`](https://cloud.gov/docs/services/external-domain-service/) for `yourOrigDomain.gov`.\n```\ncf create-service external-domain domain-with-cdn yourOrigDomain.gov -c '{\"domains\": \"yourOrigDomain.gov\"}'\n```\n\nOnce your changes are merged into `main` by an administrator,\nthe `pages-redirects` app will be redeployed by CircleCI and your redirects\nshould start working within a few minutes.\n\n## Developing\n\nThis is a NodeJS-based project that uses [`npm`](https://npmjs.com/) for managing node dependencies.\nAfter making sure you have it installed, run `npm` to install dependencies.\n\nThe NodeJS code (called from [`build.js`](/build.js)) reads an array of sites to\nredirect from the [`pages.yml`](/pages.yml) file and inserts new NGINX rewrite rules\ninto the [`nginx.conf.njk`](/templates/nginx.conf.njk) template in [`templates/`](/templates).\nThe resulting `nginx.conf` files (one for testing in [Docker](#local-docker) and one\nfor the production site) are written to the `out/` directory.\nThe build script also produces a CloudFoundry manifest file at `out/manifest-prod.yml` for deploying this app to cloud.gov.\n\n## Testing\n\nTo run unit tests, run `npm test`.\n\n### Integration Tests\n\n#### Local Docker\n\nYou can run integration tests locally against a Docker container.\nFirst make sure you have [Docker][] and [Docker Compose][] installed, and maybe\ngive the [18F Docker guide][] a read.\n\nThen build and run tests in the docker-compose network:\n\n```sh\nnpm run build-docker \u0026\u0026 npm run test-docker\n```\n\n#### Real server\n\nTo run integration tests against a real server:\n\n```sh\nTARGET_HOST=\u003cFULL_URL_TOSERVER\u003e npm run test-integration\n```\n\nFor example:\n\n```sh\nTARGET_HOST=https://pages-redirects.app.cloud.gov npm run test-integration\n```\n\n## Deploying\n\nThis is deployed in GovCloud cloud.gov:\n\n- org: `gsa-18f-federalist`\n- space: `redirects`\n\n## CI Deployments\nThis repository contains one pipeline in concourse:\n- [__Redirects__](./ci/pipeline.yml)\n\n__Redirects__ deploys the Pages redirects app\n\n#### Pipeline credentials\nConcourse CI integrates directly with [Credhub](https://docs.cloudfoundry.org/credhub/) to provide access to credentials/secrets at job runtime. When a job is started, Concourse will resolve the parameters within the pipeline with the latest credentials using the double parentheses notation (ie. `((\u003ccredential-name\u003e))`). See more about the [credentials lookup rules](https://concourse-ci.org/credhub-credential-manager.html#credential-lookup-rules).\n\nSome credentials in this pipeline are \"compound\" credentials that use the pipeline's instance variable in conjuction with its parameterized variables to pull the correct Credhub credentials based on the pipeline instance. The following parameters are used in the proxy pipeline:\n\n|Parameter|Description|Is Compound|\n--- | --- | --- |\n|**`((deploy-env))-cf-username`**|The deployment environments CloudFoundry deployer username based on the instanced pipeline|:white_check_mark:|\n|**`((deploy-env))-cf-username`**|The deployment environments CloudFoundry deployer password based on the instanced pipeline|:white_check_mark:|\n|**`((slack-channel))`**| Slack channel | :x:|\n|**`((slack-username))`**| Slack username | :x:|\n|**`((slack-icon-url))`**| Slack icon url | :x:|\n|**`((slack-webhook-url))`**| Slack webhook url | :x:|\n|**`((gh-access-token))`**| The Github access token|:x:|\n\n##### Setting up the pipeline\nThe pipeline and each of it's instances will only needed to be set once per instance to create the initial pipeline. After the pipelines are set, updates to the respective `git-branch` source will automatically set the pipeline with any updates. See the [`set_pipeline` step](https://concourse-ci.org/set-pipeline-step.html) for more information. Run the following command with the fly CLI to set a pipeline instance:\n\n```bash\n$ fly -t \u003cConcourse CI Target Name\u003e set-pipeline -p redirects \\\n  -c ci/pipeline.yml\n```\n\n##### Getting or deleting a pipeline instance from the CLI\nTo get a pipeline instance's config or destroy a pipeline instance, Run the following command with the fly CLI to set a pipeline:\n\n```bash\n## Get a pipeline instance config\n$ fly -t \u003cConcourse CI Target Name\u003e get-pipeline \\\n  -p redirects\n\n## Destroy a pipeline\n$ fly -t \u003cConcourse CI Target Name\u003e destroy-pipeline \\\n  -p redirects\n```\n\n### Manual Deployments\n\nTo manually deploy (this should not be necessary):\n\n```sh\nnpm run build\ncf push -f out/manifest-prod.yml`\n```\n\n[18F Docker guide]: https://pages.18f.gov/dev-environment-standardization/virtualization/docker/\n[Docker]: https://www.docker.com/\n[Docker Compose]: https://docs.docker.com/compose/\n[cf-autopilot]: https://github.com/contraband/autopilot\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fcloud-gov%2Fpages-redirects","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fcloud-gov%2Fpages-redirects","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fcloud-gov%2Fpages-redirects/lists"}