MERN Stack - Webpage not visible REACT

Hello! I am trying to create a personal website using the MERN stack. I am in the process of trying to create a password protected login to enter. My database and server is connected but I’m unable to see the webpage. It might have to do with my JS or JSX compatibility, images referenced and how the app is configured. Help is much needed!

App Component:
import ‘bootstrap/dist/css/bootstrap.min.css’;
import ‘./App.css’;
import Scrollable from ‘./components/Scrollable.jsx’;
import Footer from ‘./components/Footer’;
import Menu from ‘./components/Menu’;
import axios from ‘axios’;

axios.defaults.baseURL = ‘http://localhost:5173’;
axios.defaults.withCredentials = true;

function App() {

return (






)
}

export default App;

Package JSON:
{
“name”: “personalwebsite”,
“private”: true,
“version”: “1.0.0”,
“type”: “module”,
“scripts”: {
“dev”: “vite”,
“build”: “vite build”,
“lint”: “eslint . --ext js,jsx --report-unused-disable-directives --max-warnings 0”,
“preview”: “vite preview”,
“start”: “nodemon vite.config.js”
},
“dependencies”: {
@cyntler/react-doc-viewer”: “^1.15.0”,
@react-pdf/renderer”: “^3.4.4”,
“axios”: “^1.7.2”,
“bcrypt”: “^5.1.1”,
“bootstrap”: “^5.3.3”,
“bootstrap-icons”: “^1.11.3”,
“cors”: “^2.8.5”,
“dotenv”: “^16.4.5”,
“express”: “^4.19.2”,
“mongodb”: “^6.6.2”,
“mongoose”: “^8.4.0”,
“nodemon”: “^3.1.1”,
“react”: “^18.2.0”,
“react-bootstrap”: “^2.10.2”,
“react-dom”: “^18.2.0”,
“react-icons”: “^5.2.1”,
“react-on-screen”: “^2.1.1”,
“react-pdf”: “^8.0.2”,
“react-router-dom”: “^6.23.0”
},
“devDependencies”: {
@types/react”: “^18.2.66”,
@types/react-dom”: “^18.2.22”,
@vitejs/plugin-react”: “^4.2.1”,
“autoprefixer”: “^10.4.19”,
“eslint”: “^8.57.0”,
“eslint-plugin-react”: “^7.34.1”,
“eslint-plugin-react-hooks”: “^4.6.0”,
“eslint-plugin-react-refresh”: “^0.4.6”,
“postcss”: “^8.4.38”,
“tailwindcss”: “^3.4.3”,
“vite”: “^5.2.0”
},
“description”: “This template provides a minimal setup to get React working in Vite with HMR and some ESLint rules.”,
“main”: “vite.config.js”,
“keywords”: ,
“author”: “”,
“license”: “ISC”
}

Main.jsx:
import React from ‘react’;
import ReactDOM from ‘react-dom/client’;
import App from ‘./App.jsx’;
import { createBrowserRouter, RouterProvider } from ‘react-router-dom’;
import ‘./index.css’;
import Projects from ‘./components/Projects.jsx’;
import Project from ‘./pages/Project.jsx’;
import Resume from ‘./pages/Resume.jsx’;
import Login from ‘./pages/Login.jsx’;
import Error from ‘./pages/Error.jsx’;

const router = createBrowserRouter([
{
path: ‘/’,
element: ,
errorElement:
},
{
path: ‘/home’,
element: ,
errorElement:
},
{
path: ‘/projects’,
element: ,
children: [
{
path: ‘/projects/:projectId’,
element:
}
],
errorElement:
},
{
path: ‘/resume’,
element: ,
errorElement:
},
]);

ReactDOM.createRoot(document.getElementById(‘root’)).render(
<React.StrictMode>
<RouterProvider router = { router } />
</React.StrictMode>,
)

authRoutes:
import express from ‘express’;
import cors from ‘cors’;
import { test, loginUser } from ‘…/controllers/authController.js’;
import App from ‘…/App.js’;
const router = express.Router();

//middleware
router.use(
cors({
credentials: true,
origin: ‘http://localhost:8000
})
);

router.get(‘/’, App);
router.post(‘/home’, );
router.post(‘/’, loginUser);

export default router;

authController:
import { comparePassword } from “…/helpers/auth.js”;

export function test (req, res) {
res.json(‘test is working’);
};

export async function loginUser (req, res) {
try {
const { password } = req.body;

    //Check if match
    const match = await comparePassword(password, user.password)
    if(match) {
        //assign webtoken to track throughout application
        res.json('passwords match')
    }
} catch (error) {
    console.log(error)
}

};

export default {
test,
loginUser
}
//Login API Endpoint

vite.config.js:
import { defineConfig } from ‘vite’;
import react from ‘@vitejs/plugin-react’;
import express from ‘express’;
import dotenv from ‘dotenv’;
import cors from ‘cors’;
import axios from ‘axios’;
import testRouter from ‘./src/routes/authRoutes.js’;
import mongoose from ‘mongoose’;

dotenv.config();
const app = express();

//database connection
const connectDB = async () => {
try{
await mongoose.connect(process.env.MONGO_URL), {
useNewUrlParser: true,
useUnifiedTopology: true,
};
console.log(‘Database Connected’);
} catch (error) {
console.error(‘Database NOT Connected’, error.message);
}
};

// export default connectDB;

// mongoose.connect(process.env.MONGO_URL)
// .then(() => console.log(‘Database Connected’))
// .catch((err) => console.log(‘Database NOT Connected’, err))

connectDB();

app.use(‘/’, testRouter)

const port = 5173;
app.listen(port, () => console.log(Server is running on port ${port}));

// Configuring Vite | Vite
// export default defineConfig({
// plugins: [react({ include: /.(mdx|js|jsx|ts|tsx)$/ })],
// server: {
// port: 5173
// },
// connectDB
// });

export default defineConfig(() => ({
esbuild: {
loader: “tsx”, // OR “jsx”
include: [
“src//*.jsx",
"node_modules/
/*.jsx”,
],
},
}));

Please make sure to escape your code when pasting it into the forum. You can do this by wrapping it triple backtick characters like so

```
<code goes here>
```

Alternatively you can supply a GitHub repo.

I don’t understand your project structure. Express can not serve React components. You can serve the build output.

I mean, you can hand-roll an SSR setup, but I doubt that is what you want to do. For full stack you probably should just use a meta framework for it, like Next or Remix, instead of having to do separate front and backend.


Please provide a GitHub repo instead.

https://github.com/abigailjulie/personalWebsiteV1

I’ve uploaded the project to github. Before creating the backend I was routing using react-router and now I’m not sure if it’s in conflict with the authController.
I also tried to use “react-router-dom”: “^6.23.0”, “@cyntler/react-doc-viewer”: “^1.15.0”, “@react-pdf/renderer”: “^3.4.4”, to be able to embed a pdf viewer. Each attempt was unsuccessful.

Thanks in advance for even looking into this.

I would suggest to look at some MERN stack articles/tutorials. What you have now is a SPA when you have randomly mixed in Express, you can’t serve React components, that isn’t how it works (you can server render components, but that is something completely different). The front and backend are two separate things. I also don’t know why you have added express code to the vite.config.js file, that isn’t what that file is used for.


Edit: also, unless you really want to do a “traditional” MERN stack app, as I said, I would look at meta frameworks like Next.js and Remix. It is easier to manage and is usually more than enough for a full stack app. It will still be a MERN stack app if you use MongoDB, because they use express/react/nodejs for the framework so if you use MongoDB for the database it is technically still a MERN stack app.

I’ve been following this tutorial: https://www.youtube.com/watch?v=XPC81RWOItI
The first error I’m getting is about jsx vs. js. The solutions on google either talk about an es loader or babel both of which I tried and landed here.

Thanks again for your help

Since I don’t know what error you are getting, I can’t say much, but name your React files using the .jsx file extension App.jsx (they have JSX in them).


I’m not going to watch all that. But at 19.12 you can see there are two separate folders, client and server. That is the setup you want to use.

Personally, I would suggest finding a tutorial that provides a GitHub repo with the finished code so you can check your code against it. If it also provides a starter repo, that is a bonus.

I apologize for being unclear. I did not want you to watch that video, I just wanted to explain that I have used a tutorial to arrive here. In the tutorial he uses .js and I’ve used .jsx. He uses “const component = ()=> {}” where as I’ve used “export default function (){}” so I think he’s using a different something… I’ve installed babel and possibly implemented it wrong.

But your setup is wrong, so such details doesn’t really matter. Unless you can untangle it somehow, I would suggest you start over. You can always copy and paste your old code as needed.

  1. You should name your files using .jsx (or .tsx if it is using TypeScript). The content of your Vite config should just be the config code. This is how it would look if you made a new Vite React app.
import { defineConfig } from 'vite'
import react from '@vitejs/plugin-react'

// https://vitejs.dev/config/
export default defineConfig({
  plugins: [react()],
})
  1. How you write the component doesn’t matter, but your export does. If you export it as a named export, you have to import it as such.
export const App = () => {}
import { App } from './App.jsx'


export default function App() {}
import App from './App.jsx'

I don’t know why your code is in the state is it now, but you can’t have followed a tutorial for it.

Hello there!

Redid the structure and followed the code in the example more closely. I ended up fixing it by using .jsx on the client side and .js on the server side. I’m 85% done with my website now but I’m having trouble making the website password protected. I wanted you to take a look at it since I already have this thread going but can make a question if you feel that’s more appropriate.

Thank you in advance,

Abigail