manjudte
manjudte

Reputation: 33

How to suppress custom context for static pages in Spartacus?

We have static pages configured in our Spartacus project and Spartacus is also configured with custom site context. Say, the custom param for SiteContext is custom and the URL will be www.storefront.com/custom. Then content pages will also be after custom param. Can we suppress it and just have www.storefront.com/staticPage instead of www.storefront.com/custom/staticPage?

Upvotes: 2

Views: 259

Answers (1)

Krzysztof Platis
Krzysztof Platis

Reputation: 1221

Yes, you can exclude some routes from prepending the site context to it.

Spartacus provides a custom Angular UrlSerializer - the SiteContexturlSerializer. It's responsible for prepending site context URL segments before the actual URL path.

So you should extend the Spartacus' serializer and provide your customized version, that in some cases doesn't prepend the site context. Provide it for example in your app.module:

  providers: [
    { provide: UrlSerializer, useExisting: CustomSiteContextUrlSerializer },
  ]

And here's the example implementation:

@Injectable({ providedIn: 'root' })
export class CustomSiteContextUrlSerializer extends SiteContextUrlSerializer {
  /**
 * Default Angular implementation of the `serialize` method.
 *  * Calling simply `super.serialize()` is not what we want - it would
 * execute the method of the direct parent class - Spartacus' `SiteContextUrlSerializer`.
 * To access the implementation of the super-super class, we derive it
 * directly from the prototype of `DefaultUrlSerializer`.
   */
  defaultSerialize = DefaultUrlSerializer.prototype.serialize.bind(this);

  serialize(tree: UrlTreeWithSiteContext): string {
    const url = this.defaultSerialize(tree);

    if (this.shouldExcludeContext(url)) {
      return url; // simply serialized URL (without context)
    } else {
      return super.serialize(tree); // delegate serialization to `SiteContextUrlSerializer`
    }
  }

  // I'm not sure this is really needed, but it's here for completeness:
  parse(url: string): UrlTreeWithSiteContext {
    const urlTree = super.parse(url);

    if (this.shouldExcludeContext(url)) {
      urlTree.siteContext = {}; // clear context metadata
    }

    return urlTree;
  }

  /**
   * Your custom rule for recognizing URLs that should not
   * have the context prepended.
   * For example: `/cart` and `/staticPage`.
   */
  protected shouldExcludeContext(url: string): boolean {
    return url === '/cart' || url === '/staticPage';
  }
}

Note: this solution works for any URL exclusions. They don't have to be static Angular Routes.

Upvotes: 2

Related Questions