Hone logo
Hone
Problems

Dynamic Sitemap Generator in Vue.js with TypeScript

This challenge tasks you with building a Vue.js component that dynamically generates a sitemap based on a provided data structure representing website pages and their relationships. A sitemap is a crucial tool for SEO, helping search engines understand the structure of a website. This component will take a hierarchical data structure as input and render an HTML sitemap.

Problem Description

You need to create a Vue.js component named Sitemap.vue that accepts a pages prop. The pages prop will be an array of page objects. Each page object will have the following properties:

  • name: (string) The name of the page (e.g., "Home", "About Us"). This will be used as the link text.
  • path: (string) The URL path for the page (e.g., "/", "/about").
  • children?: (PageObject[] | null) An optional array of child page objects, representing subpages. If a page has no children, this property should be null.

The component should render an unordered list (<ul>) representing the sitemap. Each page should be rendered as a list item (<li>) containing a link (<a>) to its corresponding path. Child pages should be nested within their parent's list items, creating a hierarchical structure. The component should handle cases where a page has no children gracefully.

Expected Behavior:

  • The component should render a valid HTML sitemap based on the provided pages data.
  • The sitemap should be visually hierarchical, reflecting the parent-child relationships in the data.
  • Links should point to the correct paths specified in the path property.
  • The component should handle empty pages arrays without errors.
  • The component should handle pages with no children correctly.

Edge Cases to Consider:

  • Empty pages array: The component should render an empty <ul> or a message indicating no sitemap data.
  • Circular dependencies in the data (though unlikely, consider how to prevent infinite loops).
  • Invalid paths (e.g., paths with spaces or special characters). While you don't need to validate the paths, ensure they are correctly rendered in the href attribute.
  • Deeply nested sitemaps (consider performance implications for very large sitemaps, though this is less critical for this exercise).

Examples

Example 1:

Input: pages = [
  {
    name: "Home",
    path: "/",
  },
  {
    name: "About Us",
    path: "/about",
    children: [
      {
        name: "Our Team",
        path: "/about/team",
      },
      {
        name: "Our Mission",
        path: "/about/mission",
      },
    ],
  },
]
Output:
<ul>
  <li><a href="/">Home</a></li>
  <li><a href="/about">About Us</a>
    <ul>
      <li><a href="/about/team">Our Team</a></li>
      <li><a href="/about/mission">Our Mission</a></li>
    </ul>
  </li>
</ul>
Explanation: A simple sitemap with a parent ("About Us") and two children ("Our Team", "Our Mission").

Example 2:

Input: pages = [
  {
    name: "Home",
    path: "/",
  },
  {
    name: "Contact",
    path: "/contact",
  },
]
Output:
<ul>
  <li><a href="/">Home</a></li>
  <li><a href="/contact">Contact</a></li>
</ul>
Explanation: A sitemap with two top-level pages and no children.

Example 3:

Input: pages = []
Output:
<ul></ul>
Explanation: An empty sitemap array results in an empty unordered list.

Constraints

  • The component must be written in TypeScript.
  • The component must use Vue.js's template syntax.
  • The component must accept a pages prop of type PageObject[].
  • The component should be reasonably performant for sitemaps with up to 100 pages. (Optimization for extremely large sitemaps is not required).
  • The generated HTML must be valid.

Notes

  • Consider using recursion to handle the hierarchical structure of the sitemap.
  • Think about how to efficiently render the nested lists.
  • Focus on clarity and maintainability of the code.
  • You can assume the name and path properties are always present and non-empty strings.
  • The PageObject type can be defined within the component file. It should include the name, path, and optional children properties as described above.
Loading editor...
typescript