How to prevent a view from being added to the Navigation Bar?

Hello everyone,

I have created a view called NewsWidget with the purpose of showing news articles in the home page, and here’s the code:

import {useEffect, useState} from "react";
import News from "Frontend/generated/com/nova/application/entities/News";
import {NewsArticleService} from "Frontend/generated/endpoints";
import {HorizontalLayout, VerticalLayout} from "@vaadin/react-components";


export default function NewsWidget()
{
    const [news, setNews] = useState<News[]>([]);

    const [visibleCount, setVisibleCount] = useState(3);

    const showMore = () => {
        setVisibleCount(prevCount => prevCount + 3);
    };

    const showLess = () => {
        setVisibleCount(prevCount => prevCount = 3);
    };

    useEffect(() => {
        NewsArticleService.getAllNews().then(response => {
            // Ensure we set an empty array if response is undefined
            const filteredNews = (response ?? []).filter((article): article is News => article !== undefined);
            setNews(filteredNews);
        });
    }, []);

    const formatDate = (timestamp: string) => {
        const date = new Date(timestamp);
        return date.toLocaleString('en-US', {
            day: '2-digit',
            month: '2-digit',
            year: 'numeric',
            hour: '2-digit',
            minute: '2-digit',
            hour12: true
        });
    };

    return (
        <VerticalLayout>
            {news.slice(0, visibleCount).map((article, index) => (
                <div key={index} className="news-card">
                    <HorizontalLayout style={{ justifyContent: "space-between", alignItems: "center" }}>
                        <VerticalLayout>
                            <h3>{article.title}</h3>
                            <p>{article.content}</p>
                            <small>{formatDate(article.add_date ?? "")}</small>
                        </VerticalLayout>
                        {article.image && <img src={"images/" + article.image} alt="Article Image" className="news-card-image" />}
                    </HorizontalLayout>
                </div>
            ))}
            {visibleCount < news.length && news.length != 0 && (
                <button onClick={showMore} className="show-more-button">Show More</button>
            )}
            {visibleCount >= news.length && news.length != 0 && (<button onClick={showLess} className="show-more-button">Show Less</button>)}
        </VerticalLayout>
    );
}

Here’s how it is being used in the home view:

import { ViewConfig } from '@vaadin/hilla-file-router/types.js';
import NewsWidget from "Frontend/views/widgets/news";

export const config: ViewConfig = { menu: { order: 0, icon: 'line-awesome/svg/home-solid.svg' }, title: 'Home' };

export default function HomeView() {
  return (
    <div className="flex flex-col h-full p-l text-center box-border">
      <NewsWidget/>
    </div>
  );
}

Now the Navigation Bar shows the News Widget as clickable button that navigates you to the NewsWidget view.

image

How to prevent that?

How is the NewsWidget source file named? To prevent the filesystem router to pick it automatically the file name should start with an underscore character.

2 Likes

Another alternative could be to create a ViewConfig for your view NewsWidget and set the property menu.exclude to true.

https://vaadin.com/docs/latest/hilla/guides/routing#viewconfig-options-reference

This way the NewsWidget will still be navigable, right? It is only excluded from the menu.

As @marcoc_753 mentioned the correct way of telling the FileRouter system to ignore the existence of that widget while setting up the routes is to start the file name with an underscore: _, which in this case makes the filename something like _ NewsWidget.tsx.

Related documentation: Routing: Filename conventions

If you want to have a navigable route for the NewsWidget, but only prevent it from being exposed in the menu, you can set create the ViewConfig for it like @rbrki07 mentioned:

export const config: ViewConfig = {
  menu: {
    exclude: true,
  },
};

export default function NewsWidget() {
  // ...
}

Related documentation: ViewConfig Options Reference

3 Likes

Thank you for clarification and the detailed explanation @soroosh.2 :+1: