skip to Main Content

My React app should have 2 main webpages: localhost:3001/ and localhost:3001/tags/. The issue is that loading localhost:3001/tags/ will display the contents at localhost:3001/. I can also tell that /tags/ isn’t loading properly because I set the page title for it to "Tags" but instead, "Homepage" shows as the page title.

The file structure:

.env
index.html
package.json
vite.config.ts
etc.
src/
  | App.tsx
  | main.tsx
  | tags/
    | index.html
    | tags.tsx

The main index.html has the script tag with src="/src/main.tsx". The src/tags/index.html is the same as the main index.html except with <title>Tags</title> and script tag with src="./tags.tsx".

tags.tsx has a simple "Hello world" inside the createRoot().

vite.config.ts:

import { defineConfig } from 'vite'
import react from '@vitejs/plugin-react'

export default defineConfig({
  plugins: [react()],
  server: {
    port: 3001
  },
  build: {
    outDir: 'dist',
    emptyOutDir: true,
    rollupOptions: {
      input: {
        main: 'index.html',
        tags: 'src/tags/index.html'
      }
    }
  }
 })

2

Answers


  1. Based on your comment, it seems like you just want to know how to not have to have src in the pathname.

    For that, you need to do a little restructuring:

    1. First of all, run npm i -D @types/node, so that you will properly get access to the path module within your vite config. I couldn’t use the path module properly until I did that.

    2. Next, move your index.html file into your src folder. This way, all your pages will be on the same level – relative to src, and you won’t have to handle specific cases involving src.

    3. Update the script tag src within your index.html to be src="./main.tsx".

    Next, you just need to do a few small changes to your vite config.

    import { defineConfig } from 'vite';
    import react from '@vitejs/plugin-react';
    import { resolve } from 'path';
    
    const root = resolve(__dirname, 'src');
    
    export default defineConfig({
      root,
      plugins: [react()],
      server: {
        port: 3001
      },
      build: {
        outDir: resolve(__dirname, 'dist'),
        emptyOutDir: true,
        rollupOptions: {
          input: {
            main: resolve(root, 'index.html'),
            tags: resolve(root, 'tags', 'index.html'),
          },
        },
      },
    });
    
    

    Whenever you want to add another page, just add it to the inputs here. Using resolve with root always makes sure that the pages are relative to src, which means src won’t show up in the url.

    Login or Signup to reply.
  2. To have your React app correctly handle routing between two pages (/ and /tags/) without needing to directly access HTML files like http://localhost:3001/src/tags/index.html, you need to set up proper routing using a library like React Router.

    To Set Up Routing in Your React App

    Firstly Install React Router, You first need to install the React Router library. You can do this by running:

    npm install react-router-dom
    

    Secondly Update Your App.tsx You will need to configure your routes in App.tsx. Here’s how you can set it up:

    // src/App.tsx
    import React from 'react';
    import { BrowserRouter as Router, Route, Routes } from 'react-router-dom';
    import Home from './Home'; // Import your Home component
    import Tags from './tags/tags'; // Adjust the import path if necessary
    
    const App: React.FC = () => {
      return (
        <Router>
          <Routes>
            <Route path="/" element={<Home />} />
            <Route path="/tags" element={<Tags />} />
          </Routes>
        </Router>
      );
    };
    
    export default App;
    

    Then your Home should be something like this

    // src/Home.tsx
    import React from 'react';
    
    const Home: React.FC = () => {
      return (
        <div>
          <h1>Homepage</h1>
        </div>
      );
    };
    
    export default Home;
    

    Then Update Your Tags Component, Make sure your tags.tsx component is structured properly. It can look something like this:

    // src/tags/tags.tsx
    import React from 'react';
    
    const Tags: React.FC = () => {
      return (
        <div>
          <h1>Tags</h1>
        </div>
      );
    };
    
    export default Tags;
    

    Lastly ensure index.html Points to the Correct Script: Make sure your main index.html file loads the JavaScript entry point

    <!-- index.html -->
    <html lang="en">
      <head>
        <meta charset="UTF-8" />
        <meta name="viewport" content="width=device-width, initial-scale=1.0" />
        <title>React App</title>
      </head>
      <body>
        <div id="app"></div>
        <script type="module" src="/src/main.tsx"></script>
      </body>
    </html>
    

    and finally

    Your vite.config.ts is set up well, as you have specified the input correctly for the build. Since you’re now using React Router, you won’t need to specify multiple HTML files in the rollupOptions.input section. The app will handle routing internally, so you can simplify this way

    // vite.config.ts
    import { defineConfig } from 'vite'
    import react from '@vitejs/plugin-react'
    
    export default defineConfig({
      plugins: [react()],
      server: {
        port: 3001,
        historyApiFallback: true, // This is important for React Router
      },
      build: {
        outDir: 'dist',
        emptyOutDir: true,
      }
    })
    

    you can then run >>>

    npm run dev
    
    

    so if you navigate to

    http://localhost:3001/ you will see your homepage with the title "Homepage."

    and

    so if you navigate to

    http://localhost:3001/tags to see the Tags page with the title "Tags."

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search