I would like to know whether i have understood the workings of connect-flash/bootstrap/sessions. I do see the flash messages appear as expected. My question is to do with the colors related to the 'success' and 'danger'. While the messages appear as expected i am not seeing the associated colors,
Below are bits of package.json,
{
"dependencies": {
"body-parser": "^1.18.3",
"bootstrap": "^4.1.3",
"connect-flash": "^0.1.1",
"cookie-parser": "^1.4.3",
"express": "^4.16.4",
"express-messages": "^1.0.1",
"express-session": "^1.15.6",
"express-validator": "^5.3.0",
"mongoose": "^5.3.15",
"pug": "^2.0.3"
},
"devDependencies": {
"nodemon": "^1.18.7"
}
}
In my app.js,
const express = require('express');
const path = require('path');
const mongoose = require('mongoose');
const bodyParser = require('body-parser');
const cookieParser = require('cookie-parser');
const expressValidator = require('express-validator');
const flash = require('connect-flash');
const session = require('express-session');
// express session middleware
app.use(session({
secret: 'keyboard cat',
resave: true,
saveUninitialized: true
}));
// express messages middleware
app.use(require('connect-flash')());
app.use(function (req, res, next) {
res.locals.messages = require('express-messages')(req, res);
next();
});
app.use(flash());
// my routes
let quotes = require('./routes/quotes');
let subscribers = require('./routes/subscribers');
app.use('/quotes', quotes);
app.use('/subscribers', subscribers);
// In my subscribers route,
router.post('/subscribe', function (req, res)
{
// logic to save to my database here
req.flash('success', 'Subscription confirmed.');
res.redirect('back');
});
In my services.pug file i have,
link(rel='stylesheet', href='/css/style.css')
link(rel='stylesheet' href='/node_modules/bootstrap/dist/css/bootstrap.css')
// other code in here
.container
h1 Subscribe to our newsletter
//- include subscribe.pug
form(method='POST', action= '/subscribe')
input(name = 'email',type='email', placeholder='Enter email')
button.button1(type='submit') Subscribe
!= messages('message',locals)
// at the bottom
script(src='/node_modules/jquery/dist/jquery.js')
script(src='/node_modules/bootstrap/dist/js/bootstrap.js')
In my message.pug i have,
.messages
each type in Object.keys(messages)
each message in messages[type]
div(class = "alert alert-"+ type) #{message}
Like i mentioned above the messages appear as expected. But i do not see the green color associated with success and the red for danger as i have seen in a tutorial i followed. I just see the message blended with the background color of the page. I would like to know what i am missing.
UPDATE
On checking the console on chrome i found the attached error messages. I have included the directory structure of the project as well. The bootstrap.css and jquery.js are not being found by the app.
This is where i set my public folder in app.js,
// set public folder
app.use(express.static(path.join(__dirname, 'public')));
The node_modules folder is available as well.
Thank you
You also need to serve bootstrap and jquery dist folders beside the public one:
// set public folder
app.use(express.static(path.join(__dirname, 'public')));
// serve bootstrap and jquery
app.use(express.static(path.join(__dirname, 'node_modules', 'bootstrap', 'dist')));
app.use(express.static(path.join(__dirname, 'node_modules', 'jquery', 'dist')));
and use them ( make sure styles are in head tag ):
link(rel='stylesheet' href='/css/bootstrap.css')
link(rel='stylesheet' href='/css/style.css')
and:
script(src='jquery.js')
script(src='/js/bootstrap.js')
of course in production you should use minified versions ( i.e: bootstrap.min.js ) or simply a CDN ( or both: when CDN is not available fall back to local ones )
Related
My Nextjs site builds without error on netlify. But the site looks like this and does not pick up the css. The console shows a syntax error Uncaught SyntaxError: Unexpected token '<'. The routing also does not work.
This site works fine when deployed to vercel. When I run npm run build and npm run start locally it works fine too. My scripts in package.json are as follows
"scripts": {
"dev": "next dev",
"start": "next start",
"build": "next build"
},
Previously I was using next build && next export to build my site but now I need Incremental Static Regeneration which is not supported by next export.
My netlify deploy settings are as
follows
When I use next export a link to any dynamic page that is not in getStaticPaths takes me to the home page. If I go to the url from inside the application, it works fine but a refresh takes me back to the home page. When I remove next export I am faced with the above issue in netlify.
my dynamic page code stripped down is as follows
[tag].js
import Head from "next/head";
import SearchPage from "../../components/app/SearchPage/SearchPage";
import {
fetchAllCuratedTopicsToRender,
fetchTitleAndDescription,
} from "../../services/SearchService";
const Search = ({ title, meta_description }) => {
const defaultTitle = "default title";
const defaultMetaDescription = "default meta description";
return (
<>
<Head>
<title key="title">{title || defaultTitle}</title>
<meta
name="description"
content={meta_description || defaultMetaDescription}
key="description"
/>
</Head>
<SearchPage />
</>
);
};
export default Search;
// Generates all the paths for the curated topics stored in the database
export async function getStaticPaths() {
const APIresponse = await fetchAllCuratedTopicsToRender();
const allPaths = APIresponse.map((el) => {
return { params: { tag: el.keyword } };
});
return {
paths: [...allPaths],
fallback: "blocking",
};
}
export async function getStaticProps(context) {
let titleAndDescription = {
title: "",
meta_description: "",
};
// only get title and description if there is a tag in the url
if (context.params?.tag) {
const tag = context.params.tag.toString();
titleAndDescription = await fetchTitleAndDescription(tag);
}
return {
props: {
title: titleAndDescription.title || "",
meta_description: titleAndDescription.meta_description || "",
},
revalidate: 31536000,
};
}
This would be a case of you having a redirect rule like:
/* /index.html 200
in your public folder. Statically generated sites sometimes needed that for client-side only navigation, but it won't be needed if you're using server-side stuff (including ISR). The Netlify Next.js Runtime also warns about this in your build logs. Simply removing the rule should fix it.
Is there a way to disable transpilation of es5 code (such as async functions) while in next dev?
Setting the babel preset-env does not work, and this previous answer no longer works either.
Setting the browserlist target within package.json still transpiles the code as well
As of Jan 2023 I found a few flags that help get you most of the way there.
const isProd = process.env.NODE_ENV === "production";
const nextConfig = {
webpack: (config, { dev }) => {
if (dev && Array.isArray(config.target) && config.target.includes('web')) {
config.optimization.minimize = false;
delete config.optimization.minimizer;
config.target = ["web", "es2020"];
}
return config;
}
};
if (!isProd) {
nextConfig.experimental = {
legacyBrowsers: false,
};
}
module.exports = nextConfig;
This will disable legacy browser support and use your browser list for swc, and then also changes the targets for webpack. Doesn't completely remove transpilation but it's way better than the default
Also, nextjs now supports browserslist in your package.json - source
Adding the following key to your package.json will enable most features by default:
{
"browserslist": [
"chrome 109"
]
}
Created a next.js full stack application. After production build when I run next start it returns 500 : internal server. I'm using environment varibles for hitting api.
env.development file
BASE_URL=http://localhost:3000
It was working fine in development
service.ts
import axios from 'axios';
const axiosDefaultConfig = {
baseURL: process.env.BASE_URL, // is this line reason for error?
headers: {
'Access-Control-Allow-Origin': '*'
}
};
const axio = axios.create(axiosDefaultConfig);
export class Steam {
static getGames = async () => {
return await axio.get('/api/getAppList');
};
}
Do you have a next.config.js file?
To add runtime configuration to your app open next.config.js and add the publicRuntimeConfig and serverRuntimeConfig configs:
module.exports = {
serverRuntimeConfig: {
// Will only be available on the server side
mySecret: 'secret',
secondSecret: process.env.SECOND_SECRET, // Pass through env variables
},
publicRuntimeConfig: {
// Will be available on both server and client
staticFolder: '/static',
},
}
To get access to the runtime configs in your app use next/config, like so:
import getConfig from 'next/config'
// Only holds serverRuntimeConfig and publicRuntimeConfig
const { serverRuntimeConfig, publicRuntimeConfig } = getConfig()
// Will only be available on the server-side
console.log(serverRuntimeConfig.mySecret)
// Will be available on both server-side and client-side
console.log(publicRuntimeConfig.staticFolder)
function MyImage() {
return (
<div>
<img src={`${publicRuntimeConfig.staticFolder}/logo.png`} alt="logo" />
</div>
)
}
export default MyImage
I hope this helps.
I dont think you have setup env.
You need to configure it for it to work. Try it without it and it should work fine!
I want to create routes that start with # symbol how should I structure the pages folder?
first I tried to create a folder with # as its name however it will create routes that proceed with # like www.example.com/#/something. I even tried [#topic] and #[topic] names for folders but it does not work as expected.
I want to have routes like:
www.example.com/#computer
www.example.com/#music
www.example.com/#programming
how can I approach the problem?
My Next.js version is 9.2.1
If you don't want to have a custom server, try rewrites and some regex. Next.js uses path-to-regexp under the hood.
async rewrites() {
return [
{
source: '/:userId(#[a-zA-Z0-9]+)/:id*',
destination: "/user/:userId/:id*",
}
]
}
You still will have to sprinkle
<Link href="/user/[userId]" as=`#${userId}`/>
as mentioned by other posters.
You should just change the as prop of the Link component adding the # symbol in the place you need it.
For example, if you keep you routes/structure like the example for dynamic routing provided by Next.js, changing the index.js under pages/post/[id]/ to the following:
import { useRouter } from 'next/router'
import Link from 'next/link'
import Header from '../../../components/header'
const Post = () => {
const router = useRouter()
const { id } = router.query
return (
<>
<Header />
<h1>Post: {id}</h1>
<ul>
<li>
<Link
href="/post/[id]/[comment]"
as={`/post/#${id}/first-comment`}>
<a>First comment</a>
</Link>
</li>
</ul>
</>
)
}
export default Post
will give you a URL like this: http://localhost:3000/post/#first/first-comment
I hope this helps you find your way.
As #Nico mentioned, We can approach the solution with inspiring from custom-server example in Next.js repo.
Page's structure will be like this: page->[topic]
We need to check inside server.js for any incoming request with URL that starts with # symbol, to do so we'll get help regular expressions inside express.js:
const express = require('express')
const next = require('next')
const port = parseInt(process.env.PORT, 10) || 3000
const dev = process.env.NODE_ENV !== 'production'
const app = next({ dev })
const handle = app.getRequestHandler()
app.prepare().then(() => {
const server = express()
// this will match all the URLs that start with #
// e.g. #computer, #hello
server.get('/#*', (req, res) => {
return app.render(req, res, '/[topic]', req.query)
})
server.all('*', (req, res) => {
return handle(req, res)
})
server.listen(port, err => {
if (err) throw err
console.log(`> Ready on http://localhost:${port}`)
})
})
This simply coordinates requests that start with # to [topic] component as before as handling other routes.
Inside component for client-side it is as simple as this:
<Link href="/[topic]" as=`#${topicString}`/>
You can get topicString in different ways like using query inside getInitialProps
I am working with simple express node js But my main.css file does not link with header.ejs both are the same folder shown in below picture.
I have searched on google but the problem still there.
my app.js file code
var express = require("express")
var app = express()
var request = require("request");
app.set("view engine", "ejs");
app.get("/", function(req, res){
res.render("search");
});
app.get("/results", function(req, res){
var url ="http://www.omdbapi.com/?s="+req.query.search+"&apikey=my_api_key"
request(url, function(error, response, body){
if(!error && response.statusCode == 200){
var data = JSON.parse(body)
// res.send(results["Search"]);
res.render("results",{data: data});
}
})
});
app.listen(5000,"localhost",function(){
console.log("movie search");
})
You have a wrong setup, Your view folder should only contain view files (in your case *.ejs files) but not static content.
Create another folder with name 'public' at root of your node project and move your main.css there and add the following code to serve static content.
app.use(express.static(__dirname + '/public'));
After this you should be able to access your main.css using localhost:5000/main.css If you see your content, The css import in your view file will start working.