Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Nextjs] Allow empty string for getPublicUrl #1656

Merged
merged 15 commits into from
Nov 23, 2023
Merged
Show file tree
Hide file tree
Changes from 8 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,11 @@ Our versioning strategy is as follows:
* `[templates/nextjs]` Fix custom headers. Now in cors-header plugin extends custom headers from next.config.js file. ([#1637](https://github.com/Sitecore/jss/pull/1637))
* `[sitecore-jss-react]` Fix PlaceholderCommon with using two and more dynamic placeholders. ([#1641](https://github.com/Sitecore/jss/pull/1641))
* `[templates/nextjs-multisite]` Fix site info fetch errors (now skipped) on XM Cloud rendering/editing host builds. ([#1649](https://github.com/Sitecore/jss/pull/1649))
* `[templates/nextjs]` `[sitecore-jss-nextjs]` Fix making a fetch to a nextjs api route in an editing environment, by adding additional variable publicUrl in runtime config ([#1656](https://github.com/Sitecore/jss/pull/1656))

### 🛠 Breaking Changes

* `[templates/nextjs]` `[sitecore-jss-nextjs]` Allow setting an empty string in PUBLIC_URL environment variable; PUBLIC_URL is commented out by default in .env; ([#1656](https://github.com/Sitecore/jss/pull/1656))
ambrauer marked this conversation as resolved.
Show resolved Hide resolved

## 21.5.0

Expand Down
3 changes: 2 additions & 1 deletion packages/create-sitecore-jss/src/templates/nextjs/.env
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,8 @@
# in your Sitecore configuration (see \sitecore\config\<%- appName %>.config).
# Be sure to update these values accordingly as your public endpoint changes.
# See https://jss.sitecore.com/docs/fundamentals/services/view-engine
PUBLIC_URL=http://localhost:3000
# In production non-editing environments it is desirable to use relative urls, so this may be set to empty string
#PUBLIC_URL=http://localhost:3000
yavorsk marked this conversation as resolved.
Show resolved Hide resolved

# To secure the Sitecore editor endpoint exposed by your Next.js app
# (`/api/editing/render` by default), a secret token is used. This (client-side)
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import chalk from 'chalk';
import { JssConfig } from 'lib/config';
import { ConfigPlugin } from '..';
import { getPublicUrl } from '@sitecore-jss/sitecore-jss-nextjs/utils';

/**
* This config will set fallback values for properties that were left empty
Expand All @@ -24,6 +25,7 @@ class FallbackPlugin implements ConfigPlugin {
sitecoreApiKey: config.sitecoreApiKey || 'no-api-key-set',
layoutServiceConfigurationName: config.layoutServiceConfigurationName || 'default',
sitecoreEdgeUrl: config.sitecoreEdgeUrl || 'https://edge-platform.sitecorecloud.io',
publicUrl: config.publicUrl || getPublicUrl(),
});
}
}
Expand Down
ambrauer marked this conversation as resolved.
Show resolved Hide resolved
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ const defaultConfig: JssConfig = {
defaultLanguage: process.env[`${constantCase('defaultLanguage')}`],
graphQLEndpoint: process.env[`${constantCase('graphQLEndpoint')}`],
layoutServiceConfigurationName: process.env[`${constantCase('layoutServiceConfigurationName')}`],
publicUrl: process.env[`${constantCase('publicUrl')}`],
};

generateConfig(defaultConfig);
Expand All @@ -34,10 +35,10 @@ generateConfig(defaultConfig);
function generateConfig(defaultConfig: JssConfig): void {
jssConfigFactory
.create(defaultConfig)
.then((config) => {
.then(config => {
writeConfig(config);
})
.catch((e) => {
.catch(e => {
console.error('Error generating config');
console.error(e);
process.exit(1);
Expand All @@ -55,9 +56,10 @@ function writeConfig(config: JssConfig): void {
const config = {};\n`;

// Set configuration values, allowing override with environment variables
Object.keys(config).forEach((prop) => {
Object.keys(config).forEach(prop => {
configText += `config.${prop} = process.env.${constantCase(prop)} || '${config[prop]}',\n`;
});

configText += `module.exports = config;`;

const configPath = path.resolve('src/temp/config.js');
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,4 +11,5 @@ export interface JssConfig extends Record<string, string | undefined> {
defaultLanguage?: string;
graphQLEndpoint?: string;
layoutServiceConfigurationName?: string;
publicUrl?: string;
}
Original file line number Diff line number Diff line change
Expand Up @@ -9,12 +9,27 @@ const corsHeaderPlugin = (nextConfig = {}) => {
}
return Object.assign({}, nextConfig, {
async headers() {
const extendHeaders = typeof nextConfig.headers === "function" ? await nextConfig.headers() : [];
const extendHeaders =
typeof nextConfig.headers === 'function' ? await nextConfig.headers() : [];
return [
...await extendHeaders,
...(await extendHeaders),
{
source: '/_next/:path*',
headers: [{ key: 'Access-Control-Allow-Origin', value: config.sitecoreApiHost }],
headers: [
{
key: 'Access-Control-Allow-Origin',
value: config.sitecoreApiHost.replace(/\/$/, ''),
},
],
},
{
source: '/api/:path*',
headers: [
{
key: 'Access-Control-Allow-Origin',
value: config.sitecoreApiHost.replace(/\/$/, ''),
},
],
},
];
},
Expand Down
26 changes: 24 additions & 2 deletions packages/sitecore-jss-nextjs/src/utils/utils.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import { getPublicUrl, getJssEditingSecret } from './utils';

describe('utils', () => {
describe('getPublicUrl', () => {
after(() => {
afterEach(() => {
delete process.env.PUBLIC_URL;
delete process.env.VERCEL_URL;
});
Expand Down Expand Up @@ -33,11 +33,33 @@ describe('utils', () => {
expect(() => getPublicUrl()).to.throw();
});

it('should use VERCEL_URL', () => {
it('should use VERCEL_URL if PUBLIC_URL is not defined', () => {
process.env.VERCEL_URL = 'jss.uniqueid.vercel.com';
const result = getPublicUrl();
expect(result).to.equal('https://jss.uniqueid.vercel.com');
});

it('should use PUBLIC_URL if PUBLIC_URL and VERCEL_URL are defined', () => {
process.env.VERCEL_URL = 'jss.uniqueid.vercel.com';
process.env.PUBLIC_URL = 'http://test.com';
const result = getPublicUrl();
expect(result).to.equal('http://test.com');
});

it('should use PUBLIC_URL if it is an empty string and VERCEL_URL is defined', () => {
process.env.VERCEL_URL = 'jss.uniqueid.vercel.com';
const publicUrl = '';
process.env.PUBLIC_URL = publicUrl;
const result = getPublicUrl();
expect(result).to.equal(publicUrl);
});

it('should use PUBLIC_URL if it is defined and is empty string', () => {
const publicUrl = '';
process.env.PUBLIC_URL = publicUrl;
const result = getPublicUrl();
expect(result).to.equal(publicUrl);
});
});
describe('getJssEditingSecret', () => {
after(() => {
Expand Down
10 changes: 7 additions & 3 deletions packages/sitecore-jss-nextjs/src/utils/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,20 +8,24 @@ import { isEditorActive, resetEditorChromes } from '@sitecore-jss/sitecore-jss/u
* VERCEL_URL is provided by Vercel in case if we are in Preview deployment (deployment based on the custom branch),
* preview deployment has unique url, we don't know exact url.
* Similarly, DEPLOY_URL is provided by Netlify and would give us the deploy URL
* In production non-editing environments it is desirable to use relative urls, so in that case set PUBLIC_URL = ''
*/
export const getPublicUrl = (): string => {
if (process.env.NETLIFY && process.env.DEPLOY_URL) return process.env.DEPLOY_URL;
if (process.env.VERCEL_URL) return `https://${process.env.VERCEL_URL}`;

let url = process.env.PUBLIC_URL;

if (url === undefined) {
if (process.env.NETLIFY && process.env.DEPLOY_URL) return process.env.DEPLOY_URL;
if (process.env.VERCEL_URL) return `https://${process.env.VERCEL_URL}`;

console.warn(
`${chalk.yellow.bold(
'Warning:'
)} An PUBLIC_URL environment variable is not defined. Falling back to http://localhost:3000.`
);
ambrauer marked this conversation as resolved.
Show resolved Hide resolved
url = 'http://localhost:3000';
} else {
if (url === '') return url;

try {
ambrauer marked this conversation as resolved.
Show resolved Hide resolved
new URL(url);
} catch (error) {
Expand Down