使用react-router渲染404页面来反应PWA:create-react-app

时间:2018-02-01 10:28:17

标签: javascript reactjs react-router create-react-app progressive-web-apps

仅当我将PWA添加到主屏幕并从那里运行应用程序时才会发生这种情况。 当我运行时,我没有看到这种行为移动或桌面浏览器上的应用程序。

我正在使用create-react-app构建的React应用。运行import {Injectable, Pipe, PipeTransform, ChangeDetectorRef, OnDestroy} from '@angular/core'; import {Subject} from 'rxjs/Subject'; import {LangChangeEvent, TranslateService} from '@ngx-translate/core'; @Injectable() @Pipe({ name: 'CollectionTranslation', pure: false }) export class CollectionPipe implements PipeTransform, OnDestroy { value: string; lastKey: string; onLangChange: Subject<LangChangeEvent>; constructor(private translate: TranslateService, private _ref: ChangeDetectorRef) { } updateValue(key: string, lang: string) { this.value = this.collectionTranslation(key, lang); this.lastKey = key; this._ref.markForCheck(); } transform(collectionParam: string) { // lang parameter is just here to execute the pipe each time the current lang is changed. // it's not used in the pipe if (this.lastKey === collectionParam) { return this.value; } this.updateValue(collectionParam, localStorage.getItem('kia.language')); if (!this.onLangChange) { this.onLangChange = this.translate.onLangChange.subscribe((event: LangChangeEvent) => { if (this.lastKey) { this.lastKey = null; // we want to make sure it doesn't return the same value until it's been updated this.updateValue(collectionParam, event.lang); } }); } return this.value; } private collectionTranslation(collectionParam: string, lang: string): string { let collection = ''; if (collectionParam === null || collectionParam === undefined) { return ''; } const coll = collectionParam.toUpperCase(); if (lang === 'fr') { collection = coll.startsWith('E') || coll.startsWith('S') ? 'ETE ' : 'HIVER '; } else { // Lang EN collection = coll.startsWith('E') || coll.startsWith('S') ? 'SUMMER ' : 'WINTER '; } collection = collection + coll.substring(coll.length - 2); return collection; } _dispose(): void { if (typeof this.onLangChange !== 'undefined') { this.onLangChange.unsubscribe(); this.onLangChange = undefined; } } ngOnDestroy(): void { this._dispose(); } } 并使用任何本地http服务器提供服务后,它可以正常工作。一旦我将其部署到Firebase或npm run build并在Firefox或Chrome移动浏览器上打开该网站,它似乎也能正常工作。但是,当我点击弹出窗口中的“添加到主屏幕”按钮时,它会被添加,但是从主屏幕图标打开它会呈现404路线。

如果没有路径与URL匹配,我使用react-router的now组件路由到自定义404页面。以下是我定义路由器“配置”的方法:

<Switch/>

<Router> <Switch> <Route exact path="/" component={Login} /> <Route path="/login" component={Login} /> <Route path="/sign-up" component={SignUp} /> <Route render={() => ( <div> <h1>Error 404: Not Found</h1> <Link to="/">Go Home</Link> </div>)} /> </Switch> </Router> 中的软件包版本:

  • package.json:^ 16.2.0
  • react:1.1.0
  • react-scripts:^ 4.2.2

1 个答案:

答案 0 :(得分:11)

原因是当从主屏幕打开应用程序时,它会查找由create-react-app创建的./index.html文件中提到的manifest.json路由。此路径与路由器配置中的任何路由都不匹配,因此它呈现404页面。如果没有创建404页面,则会显示空白页面,因为所有路径都将返回null。

如果您在浏览器上手动访问网址,则可以观察到相同的行为:https://website.com/index.html。该应用将呈现空白页面或404页面(如果您已创建一个页面)。

要解决此问题,请更改start_url文件中的manifest.json字段,如下所示:

{
  ...
  start_url: "/"
}

现在,当从主屏幕启动应用时,它会查找'/'路径,而不是'/index.html'