Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

SSG allow loading static assets #29236

Closed
1 task done
AmitMY opened this issue Dec 29, 2024 · 3 comments · Fixed by #29252
Closed
1 task done

SSG allow loading static assets #29236

AmitMY opened this issue Dec 29, 2024 · 3 comments · Fixed by #29252

Comments

@AmitMY
Copy link
Contributor

AmitMY commented Dec 29, 2024

Command

build

Is this a regression?

  • Yes, this behavior used to work in the previous version

The previous version in which this bug was not present was

17

Description

I am using transloco for localization.
When building (used to be prerendering) now the build process tries to render the pages.
In doing so, it hits this loader, which loads a static asset (the language in question)

@Injectable({providedIn: 'root'})
export class HttpLoader implements TranslocoLoader {
  private http = inject(HttpClient);

  getTranslation(langPath: string): Observable<Translation> {
    return this.http.get<Translation>(`assets/i18n/${langPath}.json`);
  }
}

However, the HTTP request fails, since there seems to not be an http server involved in the SSG process.

If I run this in SSR, it also fails, but that is because it can't handle the path, and requires a full URL (http://localhost:4000/assets/...)

If I accept not having a server, I need to have a similar behavior to what I do during testing:

    if (isPlatformServer(this.platformId)) {
      const path = require('path');
      const filePath = path.join(__dirname, '..', '..', '..', assetPath);
      console.error('filePath', filePath);
      const fs = require('fs');

      const data = fs.readFileSync(filePath, 'utf8');
      return of(JSON.parse(data));
    }

But this relies on node modules, and the builder errors:

The package "fs" wasn't found on the file system but is built into node. Are you trying to bundle for node? You can use "platform: 'node'" to do that, which will remove this error.

Therefore, my issues are:

  1. SSG should have some sort of way to load static assets.
  2. SSR should not need the full URL. somehow, it should understand that any path requested is under the same host as the REQUEST.

Minimal Reproduction

  1. Make a new app, with ssr and ssg ("prerender": true, "ssr": {"entry": "src/server.ts"}`)
  2. under src/assets add something.json
  3. in the AppComponent's ngOnInit function, make this.httpClient.get('/assets/something.json').subscribe()
  4. run ng build --configuration=production

Exception or Error

- SSG should have a way to load static assets
- SSR should be able to load assets using HTTP

Your Environment

Angular CLI: 19.0.6
Node: 22.0.0
Package Manager: npm 10.5.1
OS: darwin arm64

Angular: 19.0.5
... animations, common, compiler, compiler-cli, core, forms
... platform-browser, platform-browser-dynamic, platform-server
... router, service-worker

Package                         Version
---------------------------------------------------------
@angular-devkit/architect       0.1900.6
@angular-devkit/build-angular   19.0.6
@angular-devkit/core            19.0.6
@angular-devkit/schematics      19.0.6
@angular/cdk                    19.0.4
@angular/cli                    19.0.6
@angular/material               19.0.4
@angular/ssr                    19.0.6
@schematics/angular             19.0.6
rxjs                            7.8.1
typescript                      5.6.3
zone.js                         0.15.0

Anything else relevant?

In the old prerendering, it used to work.

@alan-agius4
Copy link
Collaborator

Load of assets when using SSG has been supported for some time now, Although you are required to use withFetch.

If the problem persists please provide a minimal runnable reproduction of the problem.

You can read here why this is needed. A good way to make a minimal repro is to create a new app via ng new repro-app and adding the minimum possible code to show the problem. Then you can push this repository to github and link it here.

@AmitMY
Copy link
Contributor Author

AmitMY commented Dec 29, 2024

If I set up a new app:
Image
Added public/something.json file with some content, , and added provideHttpClient(withFetch()), it indeed works.

  private http = inject(HttpClient);

  ngOnInit() {
    this.http.get('something.json').pipe(
      tap((res: any) => console.log("Success", res)),
      catchError((err: any) => {
        console.log("Error", err);
        return of(null);
      })
    ).subscribe();
  }

Indeed prints "success"


However, in my app, I am using withFetch

    provideHttpClient(withFetch(), withInterceptorsFromDi()),

But still it doesn't work:

Couldn't load translation file 'assets/i18n/en.json' dt {
  headers: e {
    headers: Map(0) {},
    normalizedNames: Map(0) {},
    lazyInit: undefined,
    lazyUpdate: null
  },
  status: 0,
  statusText: 'Unknown Error',
  url: 'assets/i18n/languages/en.json',
  ok: false,
  type: undefined,
  name: 'HttpErrorResponse',
  message: 'Http failure response for assets/i18n/languages/en.json: 0 undefined',
  error: TypeError: Invalid URL

My repository is https://github.com/sign/translate
http setup: https://github.com/sign/translate/blob/98d54014850acf6d87d743e8002f022b57a3ece6/src/app/app.config.ts#L54

@AmitMY
Copy link
Contributor Author

AmitMY commented Jan 3, 2025

Hi @alan-agius4 - any ideas on this?

alan-agius4 added a commit to alan-agius4/angular-cli that referenced this issue Jan 6, 2025
…during server fetch

Ensures proper handling of relative URLs to prevent errors in server-side fetch operations.

Closes angular#29236
alan-agius4 added a commit that referenced this issue Jan 6, 2025
…during server fetch

Ensures proper handling of relative URLs to prevent errors in server-side fetch operations.

Closes #29236
alan-agius4 added a commit that referenced this issue Jan 6, 2025
…during server fetch

Ensures proper handling of relative URLs to prevent errors in server-side fetch operations.

Closes #29236

(cherry picked from commit a0b4ea2)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
2 participants