feat: Configurable normalizeHref

Abierto
#4,584 2 comentarios 0 reacciones 0 asignados Ver en GitHub

Los mantenedores suelen responder en 1 día

Nadie ha tomado este issue todavía.

Evaluación

Dificultad
4/5
Tiempo estimado
3-5 días
Aptitud para principiantes
35/100
Tipo de issue
Nueva funcionalidad
Claridad
Bastante claro
Estado de actividad
Estancado
Stack tecnológico
typescript
Área
build-system

Línea de trabajo

Comienza localizando crawlAnchorsForNextUrls y standardNormalizeHref, y luego inspecciona cómo se definen y utilizan las opciones de prerenderConfig. Confirma cómo debería interactuar un hook normalizeHref configurable con el comportamiento existente de la barra final, y añade cobertura que demuestre que el comportamiento configurado se aplica mientras que el predeterminado permanece sin cambios.

Escrito por el modelo de indexación a partir del texto del issue.

Descripción

Feature: Want this? Upvote it!
Prerequisites
Describe the Feature Request

In order to prerender pages it would be great to configure the behaviour of normalizing the href.

Describe the Use Case

I have hrefs with and without trailing slash. The only thing which can be configured is using trailing slash or not. If setting trailing slash to true all href will have a trailing slash in the end, if set to false all href won`t have a trailing slash. I would suggest to add the possibility make this configurable. Either by adding a the possibility to do something like trailingSlash: 'source' in the config or by adding the possibility to overwrite the standardNormalizeHref function.

Describe Preferred Solution

option number 1

const standardNormalizeHref = (prerenderConfig, diagnostics, url) => {
  try {
    if (url != null && typeof url.href === 'string') {
      let href = url.href.trim();
      if (prerenderConfig.trailingSlash === true) {
        // url should have a trailing slash
        if (!href.endsWith('/')) {
          const parts = url.pathname.split('/');
          const lastPart = parts[parts.length - 1];
          if (!lastPart.includes('.')) {
            // does not end with a slash and last part does not have a dot
            href += '/';
          }
        }
      }
      else if (prerenderConfig.trailingSlash === false ){
        // url should NOT have a trailing slash
        if (href.endsWith('/') && url.pathname !== '/') {
          // this has a trailing slash and it's not the root path
          href = href.slice(0, -1);
        }
      }
      return href;
    }
  }
  catch (e) {
    catchError(diagnostics, e);
  }
  return null;
};

option number 2

const crawlAnchorsForNextUrls = (prerenderConfig, diagnostics, baseUrl, currentUrl, parsedAnchors) => {
  if (!Array.isArray(parsedAnchors) || parsedAnchors.length === 0) {
    return [];
  }
  const basePathParts = baseUrl.pathname.split('/');
  // filterAnchor(): filter which anchors to actually crawl
  // normalizeUrl(): normalize href strings into URL objects
  // filterUrl(): filter which urls to actually crawl
  // normalizeHref(): normalize URL objects into href strings
  return parsedAnchors
    .filter((anchor) => {
    // filter which anchors to actually crawl
    if (typeof prerenderConfig.filterAnchor === 'function') {
      // user filterAnchor()
      try {
        const userFilterAnchor = prerenderConfig.filterAnchor(anchor, currentUrl);
        if (userFilterAnchor === false) {
          return false;
        }
      }
      catch (e) {
        // user filterAnchor() error
        catchError(diagnostics, e);
        return false;
      }
    }
    // standard filterAnchor()
    return standardFilterAnchor(diagnostics, anchor);
  })
    .map((anchor) => {
    // normalize href strings into URL objects
    if (typeof prerenderConfig.normalizeUrl === 'function') {
      try {
        // user normalizeUrl()
        const userNormalizedUrl = prerenderConfig.normalizeUrl(anchor.href, currentUrl);
        // standard normalizeUrl(), after user normalized
        return standardNormalizeUrl(diagnostics, userNormalizedUrl.href, currentUrl);
      }
      catch (e) {
        // user normalizeUrl() error
        catchError(diagnostics, e);
      }
    }
    // standard normalizeUrl(), no user normalized
    return standardNormalizeUrl(diagnostics, anchor.href, currentUrl);
  })
    .filter((url) => {
    // filter which urls to actually crawl
    if (typeof prerenderConfig.filterUrl === 'function') {
      // user filterUrl()
      try {
        const userFilterUrl = prerenderConfig.filterUrl(url, currentUrl);
        if (userFilterUrl === false) {
          return false;
        }
      }
      catch (e) {
        // user filterUrl() error
        catchError(diagnostics, e);
        return false;
      }
    }
    // standard filterUrl()
    return standardFilterUrl(diagnostics, url, currentUrl, basePathParts);
  })
    .map((url) => {
    

if (typeof prerenderConfig.normalizeHref === 'function') {
      try {
        // user normalizeHref()
        return  prerenderConfig.normalizeHref(prerenderConfig, diagnostics, url);
      }
      catch (e) {
        // user normalizeUrl() error
        catchError(diagnostics, e);
      }
    }
// standard normalize href
    // normalize URL objects into href strings
    return standardNormalizeHref(prerenderConfig, diagnostics, url);
  })
    .reduce((hrefs, href) => {
    // remove any duplicate hrefs from the array
    if (!hrefs.includes(href)) {
      hrefs.push(href);
    }
    return hrefs;
  }, [])
    .sort((a, b) => {
    // sort the hrefs so the urls with the least amount
    // of directories are first, then by alphabetical
    const partsA = a.split('/').length;
    const partsB = b.split('/').length;
    if (partsA < partsB)
      return -1;
    if (partsA > partsB)
      return 1;
    if (a < b)
      return -1;
    if (a > b)
      return 1;
    return 0;
  });
};
Describe Alternatives

No response

Related Code

No response

Additional Information

No response

Lenguaje dominante
TypeScript
Estrellas
13.2k
Forks
865
Merge medio
2 d 16 h
PR fusionados (30 d)
29

Preparar el entorno

Primeros pasos

  1. Lee el issue completo y luego la guía de contribución del proyecto.
  2. Comenta en el issue que vas a ocuparte — evita que dos personas hagan lo mismo.
  3. Haz un fork del repositorio y trabaja en una rama.
  4. Abre un pull request que haga referencia al número del issue.

Más de stenciljs/core

Todos los issues de stenciljs/core

Issues similares

Más issues de TypeScript

Recibe los nuevos issues en tu correo

Un resumen breve de issues de GitHub para principiantes.