Access images in public folder from pages/api in nextJS using nodemailer [duplicate] - next.js

This question already has an answer here:
Next.js: How to get static assets from within getStaticProps
(1 answer)
Closed 3 months ago.
using these versions
"next": "12.0.7"
"nodemailer": "^6.7.2"
I am building a mailing service using NextJS, but i encountered some problems:
gmail not rendering the images (solved by sending as attachment the images i want to render)
In production, the mailing service can't find the images inside the public folder
Mails sent in dev environment work perfect, but in production the images don't render
I have the following structure
pages
-api
-contact.js
public
-images
-image_name.png
in contact.js
as suggested here
...
mailData = {
from: process.env.THE_EMAIL,
to: req.body.email,
subject: `SOME_SUBJECT`,
attachments: [
{
filename: 'image_name.png',
path: 'public/images/image_name.png',
cid: 'SOME_ID_FOR_NODEMAILER',
}
]}
...
When Im working in localhost, the mailing service works perfect and the images are found, but when is in production (deployed with Vercel) it cannot find the images.
Any thoughts or alternatives?
Should i host the images in a CDN and forget about it?

this worked for me, following this article
const mailOptions = {
from: 'fromEmailAddress#gmail.com',
to: email,
replyTo: email,
subject: `${emailSubject}`,
html: emailBody,
attachments: [
{
filename: `invoice-${invoiceNumber}.pdf`,
path: process.cwd() + '/public/invoice.pdf'
}
]
}

Related

Meteor Iron Router - no route definitions after Meteor v2.6 upgrade?

I've just upgraded my project to Meteor v2.6 along with all packages. Everything runs smoothly on local so I pushed to Galaxy where I'm promptly met by this error when trying to load my app:
Nothing in the codebase itself was changed, needless to say the routes have been defined and have been working fine before.
Here's an excerpt of the code:
import "/imports/ui/layouts/dashboardLayout/dashboardLayout";
import "/imports/ui/layouts/landingLayout/landingLayout";
import "/imports/ui/pages";
import "/imports/ui/pages/landing/landingHeader/landingHeader";
if (Meteor.isClient && Meteor.isProduction) {
Router.plugin("reywood:iron-router-ga");
}
Router.configure({
trackPageView: true,
});
Router.onAfterAction(() => {
window.scrollTo(0, 0);
});
Router.route("/", {
name: "landing",
layoutTemplate: "landingLayout",
action: function () {
this.render("landingHeader", { to: "header" });
this.render("landingContent", {
to: "content",
data: { signUp: !!this.params.query.signUp },
});
},
});
Below the diff in the versions file>
Given it runs fine locally but has issues in Production, I wonder whether the problem is this bit of code here:
if (Meteor.isClient && Meteor.isProduction) {
Router.plugin("reywood:iron-router-ga");
}
I don't know why it's there (it's not my code originally) but I've noticed that the reywood:iron-router-ga version seems to have been downgraded for some reason during the upgrade:
When I try to force an update to reywood:iron-router-ga in the vain hope that by getting it back to v2.0.1 it will start working again, I get the message that "The specified packages are at their latest compatible versions".
Has anyone encountered this before/any idea what's going on? I'm not a fan of forcing different behaviour in Production from Dev as that obviously makes testing difficult/pointless - unless there's a good reason for it. Can anyone shed any light?

How to allow all domains for Image nextjs config?

I have various image url and changes over time (the image are taken for web by url address and not locally or from a private storage). In order to render <Image /> tag , domains should be passed on to nextjs config.
It isn't possible to pass in 100s of url over time.
How to allow all domains ?
/** #type {import('next').NextConfig} */
const nextConfig = {
reactStrictMode: true,
images: {
domains: [
"img.etimg.com",
"assets.vogue.com",
"m.media-amazon.com",
"upload.wikimedia.org",
],
},
};
module.exports = nextConfig;
I tried this but dint work,
"*.com"
It works for me, accordingly next.js documentation:
const nextConfig = {
images: {
remotePatterns: [
{
protocol: "https",
hostname: "**",
},
],
},
};
next.js remote patterns
The Domain is required to be explicit per their documentation
To protect your application from malicious users, you must define a list of image provider domains that you want to be served from the Next.js Image Optimization API.
You can also see that the source code allows for url's to be evaluated, a wildcard is not accepted.
https://github.com/vercel/next.js/blob/canary/packages/next/client/image.tsx#L864
Solve
You should look at a proxy like cloudinary or imgix and allow those domains in the next.config and use their fetch features to load external image.
i.e
With cloudinary as the allowed domain
module.exports = {
images: {
domains: ['res.cloudinary.com'],
},
};
and then in your code
<Image
src="https://res.cloudinary.com/demo/image/fetch/https://a.travel-assets.com/mad-service/header/takeover/expedia_marquee_refresh.jpg"
width={500}
height={500}
/>
Important
The following StackBlitz utilizes their demo account to fetch an external image from Expedia.com, you should get your own account for production.
https://stackblitz.com/edit/nextjs-pxrg99?file=pages%2Findex.js

Creating a NavigationStrategy in Aurelia

I'm trying to use Aurelia as my platform for a custom Wordpress theme.
What I want to do is define my navigation menu in Wordpress, use the Wordpress plugin for menus to expose the menus through the Wordpress API as a JSON string and then building the navigation menu in Aurelia.
Everything I have found so far involves creating a simple one line menu.
Has anyone done this or can point me in the right direction?
Since you're using server-side data to build your navigation menu, you might as well let the server do the hard work and let it generate a ready-to-use configuration for your router.
Let your plugin generate JSON like this:
{
"routes": [
{
"route": "\"...\"",
"moduleId": "\"...\"",
"settings": {
"childRoutes": [
{
"route": "\"...\"",
"moduleId": "\"...\"",
}
]
}
]
}
Then in your root view model's configureRouter you could do something like this:
async configureRouter(config, router) {
const resp = await http.fetch("api/menu-plugin-uri");
const json = await resp.json();
config.map(json.routes);
}
The child routes are stored in the settings object of the config, meaning we can use it for building a navigation menu and we can access it in child routes like so:
configureRouter(config, router) {
const parentConfig = router.parent.currentInstruction.config;
config.map(parentConfig.childRoutes);
}
That doesn't give you nice NavModels with isActive and everything, but this is about as good as it gets when it comes to nested navigation menu's currently.
I'm actually working on a plugin myself to try and address some of these limitations, though NOT ready for production yet.

Meteor Template not working for root path

I want to refer to my earlier question: Meteor Dynamic Template not working
Using components in my app is working just fine on all other pages except on the root path:
FlowRouter.route('/', {
action() {
BlazeLayout.render('mainLayout', { content: 'home' });
},
});
The same components are working just fine here.
FlowRouter.route('/dashboard', {
action() {
BlazeLayout.render('mainLayout', { content: 'dashboard' });
},
});
I have imported the same components in both home.js and dashboard.js. The location of the files are the same and the imports are identical. My components work on all pages, but not if is root path.
Any help will be greatly appreciated. Thank you!
This was actually solved by a complete reboot. I tried restarting the application multiple times without luck.

Adding Facebook login to Angular2-Meteor app

I am attempting to add Facebook authentication into an Angular2-Meteor app that started off as the Socially app from the tutorial and is slowly being modified into something less generic. There doesn't seem to be much posted on this particular use case however.
Note: I've asked in the Meteor forums and Gitter without success already.
Here are the steps I've taken:
Added Service Configuration package using
meteor add service-configuration
Created a file at server/services.ts containing (with my actual keys):
ServiceConfiguration.configurations.upsert({
"service": "facebook"
}, {
$set: {
"settings": {
"appId": “appid”,
“secret": "secret",
"loginStyle": "popup"
}
}
});
But on compile, I get an error saying
cannot find name 'ServiceConfiguration'
Which makes me think the package didn't install properly, but uninstalling/reinstalling it has not resolved the issue and it is showing in my .meteor directory.
Client side I'm calling this method with a click event on a button in a component that does have Meteor imported:
facebook() {
Meteor.loginWithFacebook((err) => {
if (err) {
//Handle error
} else {
//Handle sign in (I reroute)
this.router.navigate(['/home']);
}
})
Which throws the console error
meteor_1.Meteor.loginWithFacebook is not a function
But I suspect this is secondary to the fact that ServicesConfiguration isn't registering.
Git repo of the project is here: https://github.com/nanomoffet/ng2-starter with the referenced files being server/services.ts and client/app.ts
Currently it is not possible to use the ServiceConfiguration in TypeScript. What I did in my application was that I created a Javascript file in which I did make the ServiceConfiguration calls.
meteor add service-configuration
Create the file ./server/service-config.js
Meteor.startup(() => {
ServiceConfiguration.configurations.remove({
service: "facebook"
});
ServiceConfiguration.configurations.insert({
service: "facebook",
appId: '<APP_ID_YOU_GET_FROM FROM_FACEBOOK>',
loginStyle: "popup",
secret: '<SECRET_YOU_GET_FROM_FACEBOOK>'
});
});
I only tested it with Google and works fine for me.

Resources