How to setup NextJS Middleware [duplicate] - javascript

I have the middleware.js file within /myproject/pages/middleware.js:
export function middleware(request) {
console.log(1);
return NextResponse.redirect(new URL('/', request.url));
}
// See "Matching Paths" below to learn more
export const config = {
matcher: ['/test'],
};
Now what I expect is when i go to the page /test then it should redirect me to /. However nothing happens and I see my standard 404 page.
Any ideas why?
NextJs version: 12.2.2

Latest versions of NextJS requires user to have a single middleware on the root folder.
Instead of {root}/pages/_middleware.js, try {root}/middleware.js

For next 13.0.2 / 13.0.1
if you are using appDir: true ( experimental )
if you want to hit middleware:
put middleware.ts in root project:
( as the same hierarchy as "app" folder, not inside app folder... )
make sure tsconfig has include: [..., "middleware.ts"]
make empty "pages" folder. ( based on issue )
will hit every request:
import { NextResponse } from 'next/server'
import type { NextRequest } from 'next/server'
export function middleware(request: NextRequest ) {
console.log('lol!!!')
}
export const config = {
matcher: '/',
}

if your pages and middleware are not on the same level, then it won't work.
here is an example of middleware working with Cookies.
import { NextResponse } from "next/server";
export default function middleware(req){
let verify = req.cookies.get("loggedin");
let url = req.url
if(!verify && url.includes('/dashboard')){
return NextResponse.redirect("http://localhost:3000/");
}
if (verify && url === "http://localhost:3000/") {
return NextResponse.redirect("http://localhost:3000/dashboard");
}
}

Related

Vue Router doesn't seem to like function calls

In my router/index.js, I am trying to lazy-load the route. If I hard-code the string it is working but if I use a function (as shown) call to get that file path as a string value, it shows me an error in the console - Error: Cannot find module '../views/Login/Login.vue'. I'm using Vue 2.6.11 and Vue-router 3.5.1.
Where am I going wrong?
import Vue from 'vue'
import VueRouter from 'vue-router'
Vue.use(VueRouter)
// const filePath = (filename, foldername) => '../views/' + foldername + "/" + filename + '.vue'
const routes = [
{
path: '/',
name: 'Login',
// THIS WORKS
component: () => import('../views/Login/Login.vue')
// THIS DOES NOT, EVEN THOUGH IT IS GETTING THE EXACT SAME VALUE
// component: () => import(filePath('Login', 'Login'))
},
]
const router = new VueRouter({
routes
})
export default router
If you want to lazy-load a route, it has to be statically analyzable, like this:
component: () => import('../views/Login/Login.vue')
In your other attempt:
component: () => import(filePath('Login', 'Login'))
The import is not statically analyzable by the build tool (probably webpack). The build tool is in charge of identifying which code is being used and which code is not (that's called tree-shaking).
As it can't resolve the actual import (it would be possible only at runtime since filePath could return anything), it considers that the vue file is never referred to, and should be removed from the build.
If your actual build tool is webpack, you have to follow webpack's instructions described here: https://webpack.js.org/api/module-methods/#dynamic-expressions-in-import which states that is possible to have dynamic imports when they have a statically analyzable pattern (e.g: template literals)
You should let webpack to know in which root folder it will load the component files, so you should move ../views/ to the import parameter instead of the returned value of your function :
const filePath = (filename, foldername) => foldername + "/" + filename + '.vue'
const routes = [
{
path: '/',
name: 'Login',
component: () => import('.../views/'+filePath('Login', 'Login'))
},
]

How to not specify file type as .js in a .ts file?

My goal is to import .ts file as it is instead of specifying the file type as .js e.g import {acccessRights} from "utils/accessRights".
My expected result: I can import a method from other file without specifying the file type.
My actual result: It throws error GET http://127.0.0.1:5501/build/lights/switchLights net::ERR_ABORTED 404 (Not Found).
Temporary solution: specify the file type as .js e.g import { switchLights } from "lights/switchLights.js". However, the jest will break because it does not find the .js file.
part of index.html
<body>
<script type="module" src="app.js"></script>
</body>
part of app.ts
import { User } from "./utils/accessRights";
import { switchLights } from "./lights/switchLights";
utils/accessRights.ts
export interface User {
role: string;
}
export function userIsAdmin(user: User): boolean {
return user.role === "admin";
}
lights/switchLights.ts
import {User, userIsAdmin} from "../utils/accessRights";
let lightsCondition: boolean = false;
function switchLightsRender() {
document.getElementById("lightsCondition").innerHTML = lightsCondition ? "ON" : "OFF";;
document.getElementById("lightsButton").innerHTML = `Lights ${!lightsCondition ? "ON" : "OFF"}`;
}
export function switchLights(user: User) {
if (!userIsAdmin(user)) return false;
lightsCondition = !lightsCondition;
switchLightsRender();
return true;
}
These are the jest files for the unit tests.
test/utils/accessRights.test.ts
import {userIsAdmin, User} from "../../src/utils/accessRights";
export let userTest: User = { role: "admin" }
test('user is admin', () => {
expect(userIsAdmin(userTest)).toBe(true);
})
test/lights/switchLights.ts
import {userTest} from "../utils/accessRights.test";
import {switchLights} from "../../src/lights/switchLights";
test("lights switched ON/OFF", () => {
let lightsConditionRef = document.createElement("span");
lightsConditionRef.setAttribute("id","lightsCondition");
document.body.appendChild(lightsConditionRef);
let lightsButtonRef = document.createElement("button")
lightsButtonRef.setAttribute("id","lightsButton");
document.body.appendChild(lightsButtonRef);
expect(switchLights(userTest)).toBe(true);
})
This is one of the transpiled .ts file to a .js file
The issue is that the auto generated code does not specify the file type in the import
My expected result:
import { userIsAdmin } from "../utils/accessRights.js";
My actual result:
import { userIsAdmin } from "../utils/accessRights";
This is the auto generated file.
build/lights/switchLight.js
import { userIsAdmin } from "../utils/accessRights";
var lightsCondition = false;
function switchLightsRender() {
var lightsConditionRef = document.getElementById("lightsCondition");
if (lightsConditionRef !== null)
lightsConditionRef.innerHTML = lightsCondition ? "ON" : "OFF";
;
var lightsButtonRef = document.getElementById("lightsButton");
if (lightsButtonRef !== null)
lightsButtonRef.innerHTML = "Lights " + (!lightsCondition ? "ON" : "OFF");
}
export function switchLights(user) {
if (!userIsAdmin(user))
return false;
lightsCondition = !lightsCondition;
switchLightsRender();
return true;
}
This is your issue: How to make TypeScript output valid ES6 module import statements?
Solution:
Use a bundler. I'd suggest using parcel for now, mostly because it doesn't require any setup.
If you need to configure a lot of things and have edge cases, I would recommend using webpack.
Installing parcel
npm i -D parcel
Actually change the import in your HTML file form app.js to app.ts (or whatever your file is called).
Add an npm script to develop:
"scripts": {
"serve": "parcel index.html"
},
run npm run serve
This will host a server for you (URL in the terminal) and recompile if you change anything.
Parcel Documentation(Getting Started)

nuxtjs/router use runtime config client side

we are using nuxt 2.14.12 and #nuxtjs/router 1.5.0
we are trying to use runtime config to make some HTTP request client side.
here is our router.js
export async function createRouter(ssrContext, createDefaultRouter) {
[...]
try {
const res = await axios.get(`${config.public.apiBaseUrl}/myslug`)
} catch (e) { }
[...]
}
here is the config file
[...]
const apiBaseUrl = `${process.env.NUXT_ENV_MY_API_URL || 'http://my-dev-domain.com'}`
[...]
export default {
apiBaseUrl,
},
private: {
apiBaseUrl,
},
[...]
here is our nuxt.config.js
export default {
[...]
publicRuntimeConfig: config.public,
privateRuntimeConfig: config.private,
[...]
buildModules: [
['#nuxtjs/router', { keepDefaultRouter: true }],
],
[...]
router: {
linkActiveClass: 'current-menu-item'
},
[...]
}
we use nuxt build in our CI and later at runtime we use nuxt start
at runtime, despite on server side the env variable NUXT_ENV_MY_API_URL is correctly set, on the client site the variable looks hardcoded (I think webpack replace it) and we get the value present on build time (http://my-dev-domain.com)
is there a way to use the runtime config on the client side?
thank you

.env Nuxt JS doesn't resolve routes in generate option correctly

I'm trying to use Nuxt JS's 2.9.2 generate object to generate dynamic pages as static files using my .env file to pull a URL, I'm having difficuility in getting it to properly link up:
nuxt.config.js
require('dotenv').config();
import pkg from './package'
import axios from 'axios'
export default {
mode: 'universal',
env: {
blog_api: process.env.BLOG_API || "http://localhost:3000/articles/blogs.json"
},
/*
** Build directory
*/
generate: {
dir: 'dist-next',
routes: function () {
return axios.get(`${process.env.blog_api}`)
.then((res) => {
return res.data.blogs.map((blog) => {
return '/posts/view/' + blog.title
})
})
}
}
}
The above code, more specifically ${process.env.blog_api}, can't seem to resolve the routes, despite it working perfectly if I replace it with my own local domain.
.env
BLOG_API="http://my-local-domain.clone/articles/blogs.json"
EDIT:
Updated code with my config, http://my-local-domain.clone/articles/blogs.json is inside of static/articles
You should use dotenv module:
https://www.npmjs.com/package/dotenv
More Info about configuration with NUXT you have here:
https://samuelcoe.com/blog/nuxt-dotenv/
You probably want to set your env property in nuxt.config.js, for example:
module.exports = {
env: {
BLOG_API: process.env.BLOG_API_URL,
},
In your component, you can now use them :
makeAsyncCall({
to: process.env.BLOG_API,
})

Cannot find name 'ENV' returnTo: ENV.BASE_URI

I assume my authentication service fails to load a configuration file causing an error.
Im following along a tutorial on AUTH0.Here is the link https://auth0.com/blog/real-world-angular-series-part-2/.
I have to import a file from env.config.ts that will be used by my authentication service.Here is the code env.config.ts
const _isDev = window.location.port.indexOf('4200') > -1;
const getHost = () => {
const protocol = window.location.protocol;
const host = window.location.host;
return `${protocol}//${host}`;
};
const apiURI = _isDev ? 'http://localhost:8083/api/' : `/api/`;
export const ENV = {
BASE_URI: getHost(),
BASE_API: apiURI
};
Here is a quote from the tutorial "This code detects the host environment and sets the app's base URI and base API URI. We'll import this ENV configuration wherever we need to detect and use these URIs."
This env file is imported into a file required by auth0,
Here is my snippet of the auth.config.ts
import { ENV } from './../core/env.config';
interface AuthConfig {
CLIENT_ID: string;
CLIENT_DOMAIN: string;
AUDIENCE: string;
REDIRECT: string;
SCOPE: string;
NAMESPACE: string;
};
export const AUTH_CONFIG: AuthConfig = {
CLIENT_ID: '[xxx]',
CLIENT_DOMAIN: '[]', // e.g., kmaida.auth0.com
AUDIENCE: '[http://localhost:8083/api/]', // e.g., http://localhost:8083/api/
REDIRECT: `${ENV.BASE_URI}/callback`,
SCOPE: 'openid profile email',
NAMESPACE: 'http://myapp.com/roles'
};
Please have a look at the tutorial and maybe share what i could have missed.
The auth.service.ts uses the configutaion file as such
// Remove data from localStorage
this._clearExpiration();
this._clearRedirect();
// End Auth0 authentication session
this._auth0.logout({
clientId: AUTH_CONFIG.CLIENT_ID,
returnTo: ENV.BASE_URI
});
}
this is what my imports section looks like of auth.service.ts
import { Injectable } from '#angular/core';
import { Router } from '#angular/router';
import { BehaviorSubject, Subscription, of, timer } from 'rxjs';
import { mergeMap } from 'rxjs/operators';
import { AUTH_CONFIG } from './auth.config';
import * as auth0 from 'auth0-js';
import { ENV } from './../core/env.config';
The error emmited in my cmd reads
ERROR in src/app/auth/auth.service.ts:92:17 - error TS2304: Cannot find name >'ENV'.
92 returnTo: ENV.BASE_URI.
I also suspect the way the imports are handled from core have a problem ,as i really im not well vast with the slash imports.
I have my app directory that holds the auth and core folder as direct children.
try declaring ENV inside a constructor.
public constructor(){
const env = ENV
}
Then use it.
console.log(env.BASE_URI)

Categories