admin管理员组文章数量:1309963
I'm trying to deploy an Angular app to GitHub Pages. I'm using Angular 19 and Node 22. I've been days on it but due to different versions and tutorials I'm quite confused on how to deploy my app and keep getting an error where only the main page shows up but the Json files from the services folder do not show and I get a 404 on the console. When I refresh the page, it then shows me a 404 on the ui as the routing seems to break. The way I'm trying to deploy the app is by building the docs
folder with npm run build
command, removing the browser folder and pushing to the GitHub master branch.
This is my configuration on GitHub Pages:
And here my related files:
// package.json
{
"name": "bible-quiz",
"version": "0.0.0",
"scripts": {
"ng": "ng",
"start": "ng serve",
"build": "ng build --configuration=production --output-path docs --base-href /bible-quiz/ && mv docs/browser/* docs/ && rmdir docs/browser",
"watch": "ng build --watch --configuration development",
"test": "ng test"
},
"private": true,
"dependencies": {
"@angular/animations": "^19.1.0",
"@angular/common": "^19.1.0",
"@angular/compiler": "^19.1.0",
"@angular/core": "^19.1.0",
"@angular/forms": "^19.1.0",
"@angular/platform-browser": "^19.1.0",
"@angular/platform-browser-dynamic": "^19.1.0",
"@angular/router": "^19.1.0",
"@tailwindcss/postcss": "^4.0.0",
"postcss": "^8.5.1",
"rxjs": "~7.8.0",
"tailwindcss": "^4.0.0",
"tslib": "^2.3.0",
"zone.js": "~0.15.0"
},
"devDependencies": {
"@angular-devkit/build-angular": "^19.1.4",
"@angular/cli": "^19.1.4",
"@angular/compiler-cli": "^19.1.0",
"@types/jasmine": "~5.1.0",
"jasmine-core": "~5.5.0",
"karma": "~6.4.0",
"karma-chrome-launcher": "~3.2.0",
"karma-coverage": "~2.2.0",
"karma-jasmine": "~5.1.0",
"karma-jasmine-html-reporter": "~2.1.0",
"typescript": "~5.7.2"
}
}
// angular.json
{
"$schema": "./node_modules/@angular/cli/lib/config/schema.json",
"version": 1,
"newProjectRoot": "projects",
"projects": {
"bible-quiz": {
"projectType": "application",
"schematics": {},
"root": "",
"sourceRoot": "src",
"prefix": "app",
"architect": {
"build": {
"builder": "@angular-devkit/build-angular:application",
"options": {
"outputPath": "docs",
"index": "src/index.html",
"browser": "src/main.ts",
"polyfills": [
"zone.js"
],
"tsConfig": "tsconfig.app.json",
"assets": [
{
"glob": "**/*",
"input": "public",
"output": "/"
}
],
"styles": [
"src/styles.css"
],
"scripts": []
},
"configurations": {
"production": {
"budgets": [
{
"type": "initial",
"maximumWarning": "500kB",
"maximumError": "1MB"
},
{
"type": "anyComponentStyle",
"maximumWarning": "4kB",
"maximumError": "8kB"
}
],
"outputHashing": "all"
},
"development": {
"optimization": false,
"extractLicenses": false,
"sourceMap": true
}
},
"defaultConfiguration": "production"
},
"serve": {
"builder": "@angular-devkit/build-angular:dev-server",
"configurations": {
"production": {
"buildTarget": "bible-quiz:build:production"
},
"development": {
"buildTarget": "bible-quiz:build:development"
}
},
"defaultConfiguration": "development"
},
"extract-i18n": {
"builder": "@angular-devkit/build-angular:extract-i18n"
},
"test": {
"builder": "@angular-devkit/build-angular:karma",
"options": {
"polyfills": [
"zone.js",
"zone.js/testing"
],
"tsConfig": "tsconfig.spec.json",
"assets": [
{
"glob": "**/*",
"input": "public"
}
],
"styles": [
"src/styles.css"
],
"scripts": []
}
}
}
}
}
}
// app.routes.ts
import {Routes} from '@angular/router';
import {SubjectListComponent} from './components/subject-list/subject-listponent';
import {SubjectComponent} from './components/subject/subjectponent';
import {InnerSubjectListComponent} from './components/inner-subject-list/inner-subject-listponent';
export const routes: Routes = [
{path: '', pathMatch: 'full', redirectTo: 'subjects'},
{path: 'subjects', component: SubjectListComponent},
{path: 'subjects/:parent-id/inner-subjects', component: InnerSubjectListComponent},
{path: 'subjects/:parent-id/inner-subjects/:inner-subject-id', component: SubjectComponent},
];
<!-- index.html -->
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>BibleQuiz</title>
<base href="/bible-quiz/">
<meta name="viewport" content="width=device-width, initial-scale=1">
<link rel="icon" type="image/x-icon" href="favicon.ico">
</head>
<body>
<app-root></app-root>
</body>
</html>
// subjects.service.ts
import {Injectable} from '@angular/core';
import {HttpClient} from '@angular/common/http';
import {Observable} from 'rxjs';
import {ISubject} from '../models/ISubject';
import {environment} from '../../environments/environment';
@Injectable({
providedIn: 'root'
})
export class SubjectsService {
private subjectsUrl = environment.apiUrl + 'subjects.json';
constructor(private http: HttpClient) {
}
getSubjects(): Observable<ISubject[]> {
return this.http.get<ISubject[]>(this.subjectsUrl);
}
}
// environment.prod.ts
export const environment = {
production: true,
apiUrl: '/bible-quiz/'
};
// environment.ts
export const environment = {
production: false,
apiUrl: '/'
};
The environments have been added as it's my understanding they are needed due to GitHub Pages appending an extra /bible-quiz/ subroot to the page, but not sure this is really needed.
This is my full app:
And here the url I'm trying to load:
And an image for what I see in my console:
I'm trying to deploy an Angular app to GitHub Pages. I'm using Angular 19 and Node 22. I've been days on it but due to different versions and tutorials I'm quite confused on how to deploy my app and keep getting an error where only the main page shows up but the Json files from the services folder do not show and I get a 404 on the console. When I refresh the page, it then shows me a 404 on the ui as the routing seems to break. The way I'm trying to deploy the app is by building the docs
folder with npm run build
command, removing the browser folder and pushing to the GitHub master branch.
This is my configuration on GitHub Pages:
And here my related files:
// package.json
{
"name": "bible-quiz",
"version": "0.0.0",
"scripts": {
"ng": "ng",
"start": "ng serve",
"build": "ng build --configuration=production --output-path docs --base-href /bible-quiz/ && mv docs/browser/* docs/ && rmdir docs/browser",
"watch": "ng build --watch --configuration development",
"test": "ng test"
},
"private": true,
"dependencies": {
"@angular/animations": "^19.1.0",
"@angular/common": "^19.1.0",
"@angular/compiler": "^19.1.0",
"@angular/core": "^19.1.0",
"@angular/forms": "^19.1.0",
"@angular/platform-browser": "^19.1.0",
"@angular/platform-browser-dynamic": "^19.1.0",
"@angular/router": "^19.1.0",
"@tailwindcss/postcss": "^4.0.0",
"postcss": "^8.5.1",
"rxjs": "~7.8.0",
"tailwindcss": "^4.0.0",
"tslib": "^2.3.0",
"zone.js": "~0.15.0"
},
"devDependencies": {
"@angular-devkit/build-angular": "^19.1.4",
"@angular/cli": "^19.1.4",
"@angular/compiler-cli": "^19.1.0",
"@types/jasmine": "~5.1.0",
"jasmine-core": "~5.5.0",
"karma": "~6.4.0",
"karma-chrome-launcher": "~3.2.0",
"karma-coverage": "~2.2.0",
"karma-jasmine": "~5.1.0",
"karma-jasmine-html-reporter": "~2.1.0",
"typescript": "~5.7.2"
}
}
// angular.json
{
"$schema": "./node_modules/@angular/cli/lib/config/schema.json",
"version": 1,
"newProjectRoot": "projects",
"projects": {
"bible-quiz": {
"projectType": "application",
"schematics": {},
"root": "",
"sourceRoot": "src",
"prefix": "app",
"architect": {
"build": {
"builder": "@angular-devkit/build-angular:application",
"options": {
"outputPath": "docs",
"index": "src/index.html",
"browser": "src/main.ts",
"polyfills": [
"zone.js"
],
"tsConfig": "tsconfig.app.json",
"assets": [
{
"glob": "**/*",
"input": "public",
"output": "/"
}
],
"styles": [
"src/styles.css"
],
"scripts": []
},
"configurations": {
"production": {
"budgets": [
{
"type": "initial",
"maximumWarning": "500kB",
"maximumError": "1MB"
},
{
"type": "anyComponentStyle",
"maximumWarning": "4kB",
"maximumError": "8kB"
}
],
"outputHashing": "all"
},
"development": {
"optimization": false,
"extractLicenses": false,
"sourceMap": true
}
},
"defaultConfiguration": "production"
},
"serve": {
"builder": "@angular-devkit/build-angular:dev-server",
"configurations": {
"production": {
"buildTarget": "bible-quiz:build:production"
},
"development": {
"buildTarget": "bible-quiz:build:development"
}
},
"defaultConfiguration": "development"
},
"extract-i18n": {
"builder": "@angular-devkit/build-angular:extract-i18n"
},
"test": {
"builder": "@angular-devkit/build-angular:karma",
"options": {
"polyfills": [
"zone.js",
"zone.js/testing"
],
"tsConfig": "tsconfig.spec.json",
"assets": [
{
"glob": "**/*",
"input": "public"
}
],
"styles": [
"src/styles.css"
],
"scripts": []
}
}
}
}
}
}
// app.routes.ts
import {Routes} from '@angular/router';
import {SubjectListComponent} from './components/subject-list/subject-listponent';
import {SubjectComponent} from './components/subject/subjectponent';
import {InnerSubjectListComponent} from './components/inner-subject-list/inner-subject-listponent';
export const routes: Routes = [
{path: '', pathMatch: 'full', redirectTo: 'subjects'},
{path: 'subjects', component: SubjectListComponent},
{path: 'subjects/:parent-id/inner-subjects', component: InnerSubjectListComponent},
{path: 'subjects/:parent-id/inner-subjects/:inner-subject-id', component: SubjectComponent},
];
<!-- index.html -->
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>BibleQuiz</title>
<base href="/bible-quiz/">
<meta name="viewport" content="width=device-width, initial-scale=1">
<link rel="icon" type="image/x-icon" href="favicon.ico">
</head>
<body>
<app-root></app-root>
</body>
</html>
// subjects.service.ts
import {Injectable} from '@angular/core';
import {HttpClient} from '@angular/common/http';
import {Observable} from 'rxjs';
import {ISubject} from '../models/ISubject';
import {environment} from '../../environments/environment';
@Injectable({
providedIn: 'root'
})
export class SubjectsService {
private subjectsUrl = environment.apiUrl + 'subjects.json';
constructor(private http: HttpClient) {
}
getSubjects(): Observable<ISubject[]> {
return this.http.get<ISubject[]>(this.subjectsUrl);
}
}
// environment.prod.ts
export const environment = {
production: true,
apiUrl: '/bible-quiz/'
};
// environment.ts
export const environment = {
production: false,
apiUrl: '/'
};
The environments have been added as it's my understanding they are needed due to GitHub Pages appending an extra /bible-quiz/ subroot to the page, but not sure this is really needed.
This is my full app: https://github/francislainy/bible-quiz
And here the url I'm trying to load: https://francislainy.github.io/bible-quiz
And an image for what I see in my console:
Share Improve this question edited Feb 4 at 3:52 Francislainy Campos asked Feb 2 at 8:47 Francislainy CamposFrancislainy Campos 4,1646 gold badges53 silver badges98 bronze badges 2- It seems to be working. francislainy.github.io/bible-quiz – dapperdandev Commented Feb 2 at 8:56
- Hi, it's not working as it sometimes shows the main page, but if you inspect the terminal you'll see there are errors and the json files are not being served. I've updated the title and pasted a screenshot of the issue to make it clearer. Thank you. – Francislainy Campos Commented Feb 2 at 9:54
3 Answers
Reset to default 1It looks like your angular.json is missing fileReplacements
under configuration.production
. You need to add that section so the compiler replaces environment.ts
with environment.prod.ts
. That will ensure the correct apiUrl
is used in your services.
Angular - Using environment-specific variables in your app
"configurations": {
"production": {
"fileReplacements": [
{
"replace": "src/environments/environment.ts",
"with": "src/environments/environment.prod.ts"
}
],
…
Technically speaking environment.ts
should contain the production environment values, and you should have an environment.{env}.ts
file for non-prod environments. I would start by leaving it how you have it and adding the above snippet to your angular.json
, then adjust when you have a comfortable understanding.
Tried to find your file
https://francislainy.github.io/bible-quiz/subjects.json
and it is there
So yes, you will need the /bible-quiz
prefix.
Also check @dapperdandev awnser, it might be missing.
Edit: Now you redirect to
{path: '', pathMatch: 'full', redirectTo: 'subjects'},
I can browse https://francislainy.github.io/bible-quiz/ which redirect to
https://francislainy.github.io/bible-quiz/subjects. (which I cannot browse)
If you open network devtools you ll see that your https://francislainy.github.io/subjects.json is missing /bible-quiz/
.
So somewhere the API prefix is not working.
Seems also that your routing is not working on GH pages
After extensive discussion with @dapperdandev, it was noticed the issue seemed to do not with the deployment but with the routing for Angular apps and Github pages.
As per this blog post https://benfraserdesign.medium/deploying-an-angular-app-on-github-pages-c4dfee672968, copying the index.html file and naming it 404.html into the docs folder seems to work as a workaround for the issue.
So I updated my build command from:
"build": "ng build --configuration=production --output-path docs --base-href /bible-quiz/ && mv docs/browser/* docs/ && rmdir docs/browser",
to:
"build": "ng build --configuration=production --output-path docs --base-href /bible-quiz/ && mv docs/browser/* docs/ && rmdir docs/browser && cp docs/index.html docs/404.html",
And that fixed the issue.
PS: Other than this, I tried to use hash routing as per:
https://stackoverflow/a/75993642/6654475
But that didn't seem to fix it for my case, but maybe would be a better path for a solution if having a 404.html file as a duplicate of the index.html file may not suit your case.
本文标签: Error on building json files on Angular 19 app and GitHub Pages404 on RoutingStack Overflow
版权声明:本文标题:Error on building json files on Angular 19 app and GitHub Pages - 404 on Routing - Stack Overflow 内容由网友自发贡献,该文观点仅代表作者本人, 转载请联系作者并注明出处:http://www.betaflare.com/web/1741853142a2401186.html, 本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容,一经查实,本站将立刻删除。
发表评论