diff --git a/aio/content/file-not-found.md b/aio/content/file-not-found.md
index 46092603ce..9371fe03bf 100644
--- a/aio/content/file-not-found.md
+++ b/aio/content/file-not-found.md
@@ -7,3 +7,4 @@
We're sorry. The page you are looking for cannot be found.
+
diff --git a/aio/e2e/app.e2e-spec.ts b/aio/e2e/app.e2e-spec.ts
index 6abeb1b998..dfcd7c6b53 100644
--- a/aio/e2e/app.e2e-spec.ts
+++ b/aio/e2e/app.e2e-spec.ts
@@ -100,4 +100,12 @@ describe('site App', function() {
expect(page.getSearchResults().map(link => link.getText())).toContain('ControlValueAccessor');
});
});
+
+ describe('404 page', () => {
+ it('should search the index for words found in the url', () => {
+ page.navigateTo('http/router');
+ expect(page.getSearchResults().map(link => link.getText())).toContain('Http');
+ expect(page.getSearchResults().map(link => link.getText())).toContain('Router');
+ });
+ });
});
diff --git a/aio/src/app/embedded/embedded.module.ts b/aio/src/app/embedded/embedded.module.ts
index ac1426e33e..b65d5bda58 100644
--- a/aio/src/app/embedded/embedded.module.ts
+++ b/aio/src/app/embedded/embedded.module.ts
@@ -20,6 +20,7 @@ import { CodeTabsComponent } from './code/code-tabs.component';
import { ContributorListComponent } from './contributor/contributor-list.component';
import { ContributorComponent } from './contributor/contributor.component';
import { CurrentLocationComponent } from './current-location.component';
+import { FileNotFoundSearchComponent } from './search/file-not-found-search.component';
import { LiveExampleComponent, EmbeddedPlunkerComponent } from './live-example/live-example.component';
import { ResourceListComponent } from './resource/resource-list.component';
import { ResourceService } from './resource/resource.service';
@@ -30,7 +31,8 @@ import { TocComponent } from './toc/toc.component';
*/
export const embeddedComponents: any[] = [
ApiListComponent, CodeExampleComponent, CodeTabsComponent, ContributorListComponent,
- CurrentLocationComponent, LiveExampleComponent, ResourceListComponent, TocComponent
+ CurrentLocationComponent, FileNotFoundSearchComponent, LiveExampleComponent, ResourceListComponent,
+ TocComponent
];
/** Injectable class w/ property returning components that can be embedded in docs */
diff --git a/aio/src/app/embedded/search/file-not-found-search.component.spec.ts b/aio/src/app/embedded/search/file-not-found-search.component.spec.ts
new file mode 100644
index 0000000000..175832ef32
--- /dev/null
+++ b/aio/src/app/embedded/search/file-not-found-search.component.spec.ts
@@ -0,0 +1,49 @@
+import { ComponentFixture, TestBed } from '@angular/core/testing';
+import { By } from '@angular/platform-browser';
+import { Subject } from 'rxjs/Subject';
+import { LocationService } from 'app/shared/location.service';
+import { MockLocationService } from 'testing/location.service';
+import { SearchResults } from 'app/search/interfaces';
+import { SearchResultsComponent } from 'app/shared/search-results/search-results.component';
+import { SearchService } from 'app/search/search.service';
+import { FileNotFoundSearchComponent } from './file-not-found-search.component';
+
+
+describe('FileNotFoundSearchComponent', () => {
+ let element: HTMLElement;
+ let fixture: ComponentFixture;
+ let searchService: SearchService;
+ let searchResultSubject: Subject;
+
+ beforeEach(() => {
+
+ TestBed.configureTestingModule({
+ declarations: [ FileNotFoundSearchComponent, SearchResultsComponent ],
+ providers: [
+ { provide: LocationService, useValue: new MockLocationService('base/initial-url?some-query') },
+ SearchService
+ ]
+ });
+
+ fixture = TestBed.createComponent(FileNotFoundSearchComponent);
+ searchService = TestBed.get(SearchService);
+ searchResultSubject = new Subject();
+ spyOn(searchService, 'search').and.callFake(() => searchResultSubject.asObservable());
+ fixture.detectChanges();
+ element = fixture.nativeElement;
+ });
+
+ it('should run a search with a query built from the current url', () => {
+ expect(searchService.search).toHaveBeenCalledWith('base initial url');
+ });
+
+ it('should pass through any results to the `aio-search-results` component', () => {
+ const searchResultsComponent = fixture.debugElement.query(By.directive(SearchResultsComponent)).componentInstance;
+ expect(searchResultsComponent.searchResults).toBe(null);
+
+ const results = { query: 'base initial url', results: []};
+ searchResultSubject.next(results);
+ fixture.detectChanges();
+ expect(searchResultsComponent.searchResults).toEqual(results);
+ });
+});
diff --git a/aio/src/app/embedded/search/file-not-found-search.component.ts b/aio/src/app/embedded/search/file-not-found-search.component.ts
new file mode 100644
index 0000000000..119b118739
--- /dev/null
+++ b/aio/src/app/embedded/search/file-not-found-search.component.ts
@@ -0,0 +1,23 @@
+import { Component, OnInit } from '@angular/core';
+import { Observable } from 'rxjs/Observable';
+import { LocationService } from 'app/shared/location.service';
+import { SearchResults } from 'app/search/interfaces';
+import { SearchService } from 'app/search/search.service';
+
+@Component({
+ selector: 'aio-file-not-found-search',
+ template:
+ `Let's see if any of these search results help...
+ `
+})
+export class FileNotFoundSearchComponent implements OnInit {
+ searchResults: Observable;
+ constructor(private location: LocationService, private search: SearchService) {}
+
+ ngOnInit() {
+ this.searchResults = this.location.currentPath.switchMap(path => {
+ const query = path.split(/\W+/).join(' ');
+ return this.search.search(query);
+ });
+ }
+}
diff --git a/aio/src/styles/2-modules/_search-results.scss b/aio/src/styles/2-modules/_search-results.scss
index 42cc6798ae..fc71cea5dc 100644
--- a/aio/src/styles/2-modules/_search-results.scss
+++ b/aio/src/styles/2-modules/_search-results.scss
@@ -29,6 +29,24 @@ aio-search-results {
}
}
+aio-search-results.embedded .search-results {
+ padding: 0;
+ color: inherit;
+ width: auto;
+ max-height: 100%;
+ position: relative;
+ background-color: inherit;
+ box-shadow: none;
+ box-sizing: border-box;
+
+ .search-area a {
+ color: lighten($darkgray, 10);
+ &:hover {
+ color: $accentblue;
+ }
+ }
+}
+
.search-area {
display: flex;
flex-direction: column;