maxwellmattryan
maxwellmattryan

Reputation: 123

Why am I getting a blank screen on my Angular app (on mobile only)?

I've written an application using Angular 10 recently. Everything is working well except for this problem where only the homepage of the site will load on mobile (Chrome, Safari). Any other URL accessed directly from the search bar will not load and results in a blank screen, however if you visit the homepage first then navigate to other URLs they work just fine.

I feel like this could be something with the router. I have modules being lazily loaded in app-routing.module.ts, but I don't know enough to know if this is something that would make this bug happen.

I'm also not too sure what code to post for this but I'll just include what I think may be relevant. I'll be happy to post more snippets if needed.

app-routing.module.ts

import { NgModule } from '@angular/core';
import { RouterModule, Routes } from '@angular/router';

const routes: Routes = [
    { 
        path: '',
        pathMatch: 'full',
        loadChildren: () => import('@ui/modules/home/home.module').then(m => m.HomeModule)
    },
    {
        path: 'admin',
        loadChildren: () => import('@ui/modules/admin/admin.module').then(m => m.AdminModule)
    },
    {
        path: 'blog',
        loadChildren: () => import('@ui/modules/blog/blog.module').then(m => m.BlogModule)
    },
    {
        path: 'portfolio',
        loadChildren: () => import('@ui/modules/portfolio/portfolio.module').then(m => m.PortfolioModule)
    },
    {
        path: '**',
        redirectTo: '/'
    }
];

@NgModule({
    imports: [RouterModule.forRoot(routes, {
            onSameUrlNavigation: 'reload',
            scrollPositionRestoration: 'top'
        })
    ],
    exports: [RouterModule]
})
export class AppRoutingModule { }

app.module.ts (I have some extra stuff for a markdown library, can just ignore it)

import { NgModule } from '@angular/core';
import { BrowserAnimationsModule } from '@angular/platform-browser/animations';
import { BrowserModule } from '@angular/platform-browser';
import { FormsModule, ReactiveFormsModule } from '@angular/forms';
import { HttpClient, HttpClientModule } from '@angular/common/http';
import { ServiceWorkerModule } from '@angular/service-worker';

import { MarkdownModule, MarkedOptions, MarkedRenderer } from 'ngx-markdown';

import { AppComponent } from './app.component';
import { AppRoutingModule } from './app-routing.module';

import { environment } from '@ui/environments/environment';
import { CoreModule } from '@ui/core/core.module';
import { MaterialModule } from '@ui/modules/material/material.module';

export function markedOptionsFactory(): MarkedOptions {
    const renderer = new MarkedRenderer();
    const linkRenderer = renderer.link;

    renderer.link = (href, title, text) => {
        const html = linkRenderer.call(renderer, href, title, text);
        return html.replace(/^<a /, '<a role="link" target="_blank" rel="nofollow noopener noreferrer" ');
    }

    return {
        renderer,
        gfm: true,
        breaks: false,
        pedantic: false,
        smartLists: true,
        smartypants: false,
    };
}

@NgModule({
    declarations: [AppComponent],
    imports: [
        AppRoutingModule,
        BrowserAnimationsModule,
        BrowserModule,
        CoreModule,
        FormsModule,
        HttpClientModule,
        MarkdownModule.forRoot({
            loader: HttpClient,
            markedOptions: {
                provide: MarkedOptions,
                useFactory: markedOptionsFactory
            }
        }),
        MaterialModule,
        ReactiveFormsModule,
        ServiceWorkerModule.register('ngsw-worker.js', { enabled: environment.production, registrationStrategy: 'registerImmediately' })
    ],
    bootstrap: [AppComponent]
})
export class AppModule { }

main.ts

import { enableProdMode } from '@angular/core';
import { platformBrowserDynamic } from '@angular/platform-browser-dynamic';

import { AppModule } from './app/app.module';
import { environment } from './environments/environment';

if (environment.production) {
    enableProdMode();
}

platformBrowserDynamic().bootstrapModule(AppModule)
    .catch(err => console.error(err));

Thanks for the help!

Upvotes: 1

Views: 2231

Answers (2)

maxwellmattryan
maxwellmattryan

Reputation: 123

SOLUTION - While a fallback solution probably would've worked, I had been using http-server to serve my app, which is not necessarily intended for SPAs. I switched to serve and it works just fine!

Upvotes: 0

Shashan Sooriyahetti
Shashan Sooriyahetti

Reputation: 878

Hi you need fallback configuration https://angular.io/guide/deployment#fallback-configuration-examples

When I host Angular apps in Apache I need to add .htaccess file,

<IfModule mod_rewrite.c>
    RewriteEngine on

    # Don't rewrite files or directories
    RewriteCond %{REQUEST_FILENAME} -f [OR]
    RewriteCond %{REQUEST_FILENAME} -d
    RewriteRule ^ - [L]

    # Rewrite everything else to index.html
    # to allow html5 state links
    RewriteRule ^ index.html [L]
</IfModule>

Upvotes: 1

Related Questions