render()

in src/amo/components/Link/index.js [50:129]


  render() {
    const {
      clientApp,
      children,
      dispatch,
      external,
      externalDark,
      href,
      lang,
      prependClientApp,
      prependLang,
      to,
      target,
      ...customProps
    } = this.props;

    const urlPrefix = this.urlPrefix({
      clientApp,
      lang,
      prependClientApp,
      prependLang,
    });

    const createLinkDest = (urlString) => {
      return urlPrefix && !urlString.startsWith(urlPrefix)
        ? joinUrl.pathname(urlPrefix, urlString)
        : urlString;
    };

    const needsExternalIcon = externalDark || external;
    const iconName = externalDark ? 'external-dark' : 'external';

    if (typeof href === 'string' && typeof to !== 'undefined') {
      throw new Error(
        'Cannot use "href" prop and "to" prop in the same Link component',
      );
    }

    if (
      typeof to !== 'undefined' &&
      ((typeof to === 'string' && !to.startsWith('/')) ||
        (to && to.pathname && !to.pathname.startsWith('/')))
    ) {
      throw new Error(
        '"to" prop cannot contain a relative path; it must start with a "/".',
      );
    }

    const linkProps = {
      ...customProps,
      target,
      rel: target === '_blank' ? 'noopener noreferrer' : customProps.rel,
    };

    if (typeof href === 'string') {
      return (
        <a {...linkProps} href={createLinkDest(href)}>
          {children}
          {needsExternalIcon ? <Icon name={iconName} /> : null}
        </a>
      );
    }

    let linkTo = to;
    if (typeof to === 'string') {
      linkTo = createLinkDest(to);
    } else if (to && to.pathname) {
      linkTo = {
        ...to,
        pathname: createLinkDest(to.pathname),
      };
    }

    return (
      <Link {...linkProps} to={linkTo}>
        {children}
        {needsExternalIcon ? <Icon name={iconName} /> : null}
      </Link>
    );
  }