diff --git a/static_src/elements/framework/mr-header/mr-header.js b/static_src/elements/framework/mr-header/mr-header.js
new file mode 100644
index 0000000..6603c85
--- /dev/null
+++ b/static_src/elements/framework/mr-header/mr-header.js
@@ -0,0 +1,427 @@
+// Copyright 2019 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+import {LitElement, html, css} from 'lit-element';
+
+import {connectStore} from 'reducers/base.js';
+import * as userV0 from 'reducers/userV0.js';
+import * as projectV0 from 'reducers/projectV0.js';
+import * as sitewide from 'reducers/sitewide.js';
+
+import {prpcClient} from 'prpc-client-instance.js';
+import 'elements/framework/mr-keystrokes/mr-keystrokes.js';
+import '../mr-dropdown/mr-dropdown.js';
+import '../mr-dropdown/mr-account-dropdown.js';
+import './mr-search-bar.js';
+
+import {SHARED_STYLES} from 'shared/shared-styles.js';
+
+import {logEvent} from 'monitoring/client-logger.js';
+
+/**
+ * @type {Object<string, string>} JS coding of enum values from
+ *    appengine/monorail/api/v3/api_proto/project_objects.proto.
+ */
+const projectRoles = Object.freeze({
+  OWNER: 'Owner',
+  MEMBER: 'Member',
+  CONTRIBUTOR: 'Contributor',
+  NONE: '',
+});
+
+/**
+ * `<mr-header>`
+ *
+ * The header for Monorail.
+ *
+ */
+export class MrHeader extends connectStore(LitElement) {
+  /** @override */
+  static get styles() {
+    return [
+      SHARED_STYLES,
+      css`
+        :host {
+          color: var(--chops-header-text-color);
+          box-sizing: border-box;
+          background: hsl(221, 67%, 92%);
+          width: 100%;
+          height: var(--monorail-header-height);
+          display: flex;
+          flex-direction: row;
+          justify-content: flex-start;
+          align-items: center;
+          z-index: 800;
+          background-color: var(--chops-primary-header-bg);
+          border-bottom: var(--chops-normal-border);
+          top: 0;
+          position: fixed;
+          padding: 0 4px;
+          font-size: var(--chops-large-font-size);
+        }
+        @media (max-width: 840px) {
+          :host {
+            position: static;
+          }
+        }
+        a {
+          font-size: inherit;
+          color: var(--chops-link-color);
+          text-decoration: none;
+          display: flex;
+          align-items: center;
+          justify-content: center;
+          height: 100%;
+          padding: 0 4px;
+          flex-grow: 0;
+          flex-shrink: 0;
+        }
+        a[hidden] {
+          display: none;
+        }
+        a.button {
+          font-size: inherit;
+          height: auto;
+          margin: 0 8px;
+          border: 0;
+          height: 30px;
+        }
+        .home-link {
+          color: var(--chops-gray-900);
+          letter-spacing: 0.5px;
+          font-size: 18px;
+          font-weight: 400;
+          display: flex;
+          font-stretch: 100%;
+          padding-left: 8px;
+        }
+        a.home-link img {
+          /** Cover up default padding with the custom logo. */
+          margin-left: -8px;
+        }
+        a.home-link:hover {
+          text-decoration: none;
+        }
+        mr-search-bar {
+          margin-left: 8px;
+          flex-grow: 2;
+          max-width: 1000px;
+        }
+        i.material-icons {
+          font-size: var(--chops-icon-font-size);
+          color: var(--chops-primary-icon-color);
+        }
+        i.material-icons[hidden] {
+          display: none;
+        }
+        .right-section {
+          font-size: inherit;
+          display: flex;
+          align-items: center;
+          height: 100%;
+          margin-left: auto;
+          justify-content: flex-end;
+        }
+        .hamburger-icon:hover {
+          text-decoration: none;
+        }
+      `,
+    ];
+  }
+
+  /** @override */
+  render() {
+    return this.projectName ?
+        this._renderProjectScope() : this._renderNonProjectScope();
+  }
+
+  /**
+   * @return {TemplateResult}
+   */
+  _renderProjectScope() {
+    return html`
+      <link href="https://fonts.googleapis.com/icon?family=Material+Icons" rel="stylesheet">
+      <mr-keystrokes
+        .issueId=${this.queryParams.id}
+        .queryParams=${this.queryParams}
+        .issueEntryUrl=${this.issueEntryUrl}
+      ></mr-keystrokes>
+      <a href="/p/${this.projectName}/issues/list" class="home-link">
+        ${this.projectThumbnailUrl ? html`
+          <img
+            class="project-logo"
+            src=${this.projectThumbnailUrl}
+            title=${this.projectName}
+          />
+        ` : this.projectName}
+      </a>
+      <mr-dropdown
+        class="project-selector"
+        .text=${this.projectName}
+        .items=${this._projectDropdownItems}
+        menuAlignment="left"
+        title=${this.presentationConfig.projectSummary}
+      ></mr-dropdown>
+      <a class="button emphasized new-issue-link" href=${this.issueEntryUrl}>
+        New issue
+      </a>
+      <mr-search-bar
+        .projectName=${this.projectName}
+        .userDisplayName=${this.userDisplayName}
+        .projectSavedQueries=${this.presentationConfig.savedQueries}
+        .initialCan=${this._currentCan}
+        .initialQuery=${this._currentQuery}
+        .queryParams=${this.queryParams}
+      ></mr-search-bar>
+
+      <div class="right-section">
+        <mr-dropdown
+          icon="settings"
+          label="Project Settings"
+          .items=${this._projectSettingsItems}
+        ></mr-dropdown>
+
+        ${this._renderAccount()}
+      </div>
+    `;
+  }
+
+  /**
+   * @return {TemplateResult}
+   */
+  _renderNonProjectScope() {
+    return html`
+      <link href="https://fonts.googleapis.com/icon?family=Material+Icons" rel="stylesheet">
+      <a class="hamburger-icon" title="Main menu" hidden>
+        <i class="material-icons">menu</i>
+      </a>
+      ${this._headerTitle ?
+          html`<span class="home-link">${this._headerTitle}</span>` :
+          html`<a href="/" class="home-link">Monorail</a>`}
+
+      <div class="right-section">
+        ${this._renderAccount()}
+      </div>
+    `;
+  }
+
+  /**
+   * @return {TemplateResult}
+   */
+  _renderAccount() {
+    if (!this.userDisplayName) {
+      return html`<a href=${this.loginUrl}>Sign in</a>`;
+    }
+
+    return html`
+      <mr-account-dropdown
+        .userDisplayName=${this.userDisplayName}
+        .logoutUrl=${this.logoutUrl}
+        .loginUrl=${this.loginUrl}
+      ></mr-account-dropdown>
+    `;
+  }
+
+  /** @override */
+  static get properties() {
+    return {
+      loginUrl: {type: String},
+      logoutUrl: {type: String},
+      projectName: {type: String},
+      // Project thumbnail is set separately from presentationConfig to prevent
+      // "flashing" logo when navigating EZT pages.
+      projectThumbnailUrl: {type: String},
+      userDisplayName: {type: String},
+      isSiteAdmin: {type: Boolean},
+      userProjects: {type: Object},
+      presentationConfig: {type: Object},
+      queryParams: {type: Object},
+      // TODO(zhangtiff): Change this to be dynamically computed by the
+      //   frontend with logic similar to ComputeIssueEntryURL().
+      issueEntryUrl: {type: String},
+      clientLogger: {type: Object},
+      _headerTitle: {type: String},
+      _currentQuery: {type: String},
+      _currentCan: {type: String},
+    };
+  }
+
+  /** @override */
+  constructor() {
+    super();
+
+    this.presentationConfig = {};
+    this.userProjects = {};
+    this.isSiteAdmin = false;
+
+    this._headerTitle = '';
+  }
+
+  /** @override */
+  stateChanged(state) {
+    this.projectName = projectV0.viewedProjectName(state);
+
+    this.userProjects = userV0.projects(state);
+
+    const currentUser = userV0.currentUser(state);
+    this.isSiteAdmin = currentUser ? currentUser.isSiteAdmin : false;
+
+    const presentationConfig = projectV0.viewedPresentationConfig(state);
+    this.presentationConfig = presentationConfig;
+    // Set separately in order allow EZT pages to load project logo before
+    // the GetPresentationConfig pRPC request.
+    this.projectThumbnailUrl = presentationConfig.projectThumbnailUrl;
+
+    this._headerTitle = sitewide.headerTitle(state);
+
+    this._currentQuery = sitewide.currentQuery(state);
+    this._currentCan = sitewide.currentCan(state);
+
+    this.queryParams = sitewide.queryParams(state);
+  }
+
+  /**
+   * @return {boolean} whether the currently logged in user has admin
+   *   privileges for the currently viewed project.
+   */
+  get canAdministerProject() {
+    if (!this.userDisplayName) return false; // Not logged in.
+    if (this.isSiteAdmin) return true;
+    if (!this.userProjects || !this.userProjects.ownerOf) return false;
+    return this.userProjects.ownerOf.includes(this.projectName);
+  }
+
+  /**
+   * @return {string} The name of the role the user has in the viewed project.
+   */
+  get roleInCurrentProject() {
+    if (!this.userProjects || !this.projectName) return projectRoles.NONE;
+    const {ownerOf = [], memberOf = [], contributorTo = []} = this.userProjects;
+
+    if (ownerOf.includes(this.projectName)) return projectRoles.OWNER;
+    if (memberOf.includes(this.projectName)) return projectRoles.MEMBER;
+    if (contributorTo.includes(this.projectName)) {
+      return projectRoles.CONTRIBUTOR;
+    }
+
+    return projectRoles.NONE;
+  }
+
+  // TODO(crbug.com/monorail/6891): Remove once we deprecate the old issue
+  // filing wizard.
+  /**
+   * @return {string} A URL for the page the issue filing wizard posts to.
+   */
+  get _wizardPostUrl() {
+    // The issue filing wizard posts to the legacy issue entry page's ".do"
+    // endpoint.
+    return `${this._origin}/p/${this.projectName}/issues/entry.do`;
+  }
+
+  /**
+   * @return {string} The domain name of the current page.
+   */
+  get _origin() {
+    return window.location.origin;
+  }
+
+  /**
+   * Computes the URL the user should see to a file an issue, accounting
+   * for the case where a project has a customIssueEntryUrl to navigate to
+   * the wizard as well.
+   * @return {string} The URL that "New issue" button goes to.
+   */
+  get issueEntryUrl() {
+    const config = this.presentationConfig;
+    const role = this.roleInCurrentProject;
+    const mayBeRedirectedToWizard = role === projectRoles.NONE;
+    if (!this.userDisplayName || !config || !config.customIssueEntryUrl ||
+        !mayBeRedirectedToWizard) {
+      return `/p/${this.projectName}/issues/entry`;
+    }
+
+    const token = prpcClient.token;
+
+    const customUrl = this.presentationConfig.customIssueEntryUrl;
+
+    return `${customUrl}?token=${token}&role=${
+      role}&continue=${this._wizardPostUrl}`;
+  }
+
+  /**
+   * @return {Array<MenuItem>} the dropdown items for the project selector,
+   *   showing which projects a user can switch to.
+   */
+  get _projectDropdownItems() {
+    const {userProjects, loginUrl} = this;
+    if (!this.userDisplayName) {
+      return [{text: 'Sign in to see your projects', url: loginUrl}];
+    }
+
+    const items = [];
+    const starredProjects = userProjects.starredProjects || [];
+    const projects = (userProjects.ownerOf || [])
+        .concat(userProjects.memberOf || [])
+        .concat(userProjects.contributorTo || []);
+
+    if (projects.length) {
+      projects.sort();
+      items.push({text: 'My Projects', separator: true});
+
+      projects.forEach((project) => {
+        items.push({text: project, url: `/p/${project}/issues/list`});
+      });
+    }
+
+    if (starredProjects.length) {
+      starredProjects.sort();
+      items.push({text: 'Starred Projects', separator: true});
+
+      starredProjects.forEach((project) => {
+        items.push({text: project, url: `/p/${project}/issues/list`});
+      });
+    }
+
+    if (items.length) {
+      items.push({separator: true});
+    }
+
+    items.push({text: 'All projects', url: '/hosting/'});
+    items.forEach((item) => {
+      item.handler = () => this._projectChangedHandler(item.url);
+    });
+    return items;
+  }
+
+  /**
+   * @return {Array<MenuItem>} dropdown menu items to show in the project
+   *   settings menu.
+   */
+  get _projectSettingsItems() {
+    const {projectName, canAdministerProject} = this;
+    const items = [
+      {text: 'People', url: `/p/${projectName}/people/list`},
+      {text: 'Development Process', url: `/p/${projectName}/adminIntro`},
+      {text: 'History', url: `/p/${projectName}/updates/list`},
+    ];
+
+    if (canAdministerProject) {
+      items.push({separator: true});
+      items.push({text: 'Administer', url: `/p/${projectName}/admin`});
+    }
+    return items;
+  }
+
+  /**
+   * Records Google Analytics events for when users change projects using
+   * the selector.
+   * @param {string} url which project URL the user is navigating to.
+   */
+  _projectChangedHandler(url) {
+    // Just log it to GA and continue.
+    logEvent('mr-header', 'project-change', url);
+  }
+}
+
+customElements.define('mr-header', MrHeader);
