Remix 애플리케이션에서 동적 표준 링크를 추가하는 방법

This article was originally written on my personal blog here.



몇 달 전에 Remix.run을 사용하여 내 블로그를 다시 작성했지만 내 블로그의 SEO를 개선하기 시작했을 때 표준 링크 문제에 직면했습니다. 이것에 대해 약간의 조사를 한 후 경로 데이터를 흡수하는 동적 링크 요소를 가질 수 있는 완벽한 솔루션에 도달했습니다. 내가 어떻게 얻었는지 보여 드리겠습니다.


Remix 앱의 모든 페이지에 표준 URL을 추가했는지 확인하세요. 크레딧: freepik에서 만든 테이블flatlay photo

표준 URL이란 무엇입니까?



If you already know what it is and why you need it, jump to the next section.



간단히 말해서 표준 URL은 검색 엔진에서 콘텐츠의 출처를 결정하는 데 사용됩니다. 블로그 게시물을 http://, https://및/또는 www을 통해 사용할 수 있다고 가정합니다. URL. 이 경우 검색 엔진이 다른 페이지를 중복으로 표시하고 원본 콘텐츠에 모든 크레딧을 제공할 수 있도록 일부 구조를 따르는 표준 URL을 입력하는 것이 좋습니다.

표준 URL을 사용하는 또 다른 일반적인 이유는 콘텐츠를 신디케이트하기 위해서입니다. 블로그 및 제3자 플랫폼(예: medium.com, dev.to 등)에 게시물을 게시하면 Google은 이를 duplicate content으로 간주합니다. 그것은 당신의 웹사이트의 순위를 손상시킬 수 있지만 표준 URL을 사용하면 이를 완전히 뒤집고 타사 플랫폼에서 표준 URL을 설정하여 웹사이트에 대한 모든 SEO 크레딧을 다시 얻을 수 있습니다. 이 블로그 게시물은 표준 URL에 대한 모든 것을 설명하기 위한 것이 아니므로 여전히 질문이 있는 경우 이에 대해 읽어볼 것을 적극 권장합니다here.

Even if I duplicated this post to Dev.to, I still get all the “SEO credits” to my website because of the canonical URL. Check out the canonical URL link the source of this page.


Remix.run의 링크 문제



아마도 Remix 애플리케이션에 blog.$slug.tsx와 같은 템플릿 경로가 있을 것입니다. 다음과 같이 links 함수를 사용하여 표준 URL을 추가할 수 있다고 생각했습니다(라우트 로더에서 canonicalUrl을 반환한다고 가정).

export const links: LinksFunction = ({ data }) => {

  return [{
    rel: 'canonical', href: data.canonicalUrl,
  }];
}


그러나 TypeScript는 즉시 저를 거절했고 매개변수에 데이터가 있는 객체를 허용하지 않았습니다. LinksFunction은 로더가 반환한 데이터에 액세스할 수 없으며 동적 콘텐츠를 거기에 넣을 수 없습니다.

솔루션: DynamicLinks 사용



그래서 Remix의 페이지에 동적 링크 요소를 추가하는 방법에 대해 인터넷에서 조사한 후 DynamicLinks를 사용하는 솔루션을 찾았습니다. 따라서 DynamicLinks는 Remix.run documentation에서 제공되는 것이 아니라 Remix.run 기능을 사용하여 빌드할 수 있는 유틸리티입니다.

Big thanks to who implemented it in remix-utils Open-Source library.



DynamicLinks 유틸리티는 어떻게 작동합니까?



코드를 보여주고 무슨 일이 일어나고 있는지 안내해 드리겠습니다.

export function DynamicLinks() {
  let links: LinkDescriptor[] = useMatches().flatMap((match) => {
    let fn = match.handle?.dynamicLinks;
    if (typeof fn !== 'function') return [];
    return fn({ data: match.data });
  });

  return (
    <React.Fragment>
      {links.map((link) => (
        <link {...link} key={link.integrity || JSON.stringify(link)} />
      ))}
    </React.Fragment>
  );
}


  • 먼저 useMatches 유틸리티 후크
  • 를 사용하여 일치하는 모든 경로를 얻습니다.
  • 일치하는 각 경로의 내보낸handle 상수에서 사전 정의된 dynamicLinks 함수를 찾고 경로 데이터를 매개변수로 제공하여 호출합니다(함수가 경로에 의해 정의된 경우)
  • 일치하는 모든 경로에서 링크를 수집한 후 간단히 렌더링합니다
  • .

    Remix 앱의 루트에 이 구성 요소를 배치할 수 있으며 내보낸 핸들 변수에서 dynamicLinks 기능을 정의하는 모든 경로에 대해 작동합니다.

    Remix 앱에서 DynamicLinks를 사용하는 방법



    유틸리티 사용법은 매우 간단합니다. 내 blog.$slug.tsx 모듈에서 dynamicLinks 함수를 정의하고 핸들 리믹스 정의 상수 내에서 내보냅니다.

    const dynamicLinks: DynamicLinksFunction<LoaderData> = ({ data }) => {
      return [
        {
          rel: 'canonical', href: data.canonicalUrl,
        },
      ];
    }
    
    export const handle = {
      dynamicLinks,
    };
    


    Note that this code assumes that I return canonicalUrl from my loader function.



    그런 다음 Remix 애플리케이션의 루트에 있는 구성 요소인 DynamicLinks를 렌더링하기만 하면 됩니다.

    import { DynamicLinks } from "remix-utils";
    
    export default function App() {
    
     return (
        <html lang="en">
          <head>
            {/** your head tags */}
            <DynamicLinks />
          </head>
          <body>
            {/** body tags */}
            <Outlet />
            <Scripts />
          </body>
        </html>
      );
    }
    


    그 결과 내 모든 블로그 게시물(클라이언트 및 서버 측 모두)에 동적 표준 URL이 생깁니다. 예:

    <link rel="canonical" href="https://aibolik.com/blog/how-to-add-dynamic-canonical-links-in-remix-application"/>
    


    그게 다야! 나는 처음에 LinksFunction이 로더 데이터를 지원하지 않는다는 사실에 화가 났지만(확실히 어떤 이유에서인지) Remix가 이러한 종류의 유틸리티를 구현할 수 있는 유연성을 제공하는 방식이 마음에 들었습니다. Remix.run documentation에는 모든 중첩 구성 요소에 대한 이동 경로 구현과 같은 useMatches 유틸리티 후크에 대한 더 많은 예가 있습니다.

    이 게시물을 읽어 주셔서 감사합니다. 질문이 있으시면 댓글이나 트윗에 저(_)를 태그해 주세요.

    좋은 웹페이지 즐겨찾기