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

feat(og-gen): Implement middleware and hooks #10469

Merged
merged 58 commits into from
Apr 26, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
58 commits
Select commit Hold shift + click to select a range
ec98e53
WIP
dac09 Apr 10, 2024
7dcce32
Get tests working for og plugin
dac09 Apr 11, 2024
d901f65
Merge branch 'main' of github.com:redwoodjs/redwood into feat/dc-rc-o…
dac09 Apr 12, 2024
422e36a
Move stuff to new package
dac09 Apr 12, 2024
ab12cc4
Update packagejson
dac09 Apr 12, 2024
751b5c5
Get around esm issue
dac09 Apr 12, 2024
6e297e9
Fix TS errors errywhere
dac09 Apr 12, 2024
bf03f82
Merge branch 'main' of github.com:redwoodjs/redwood into feat/dc-rc-o…
dac09 Apr 12, 2024
e7eecd8
Undo internal package.json change
dac09 Apr 12, 2024
3d807f5
Add cjs wrappers for middleware and hooks
dac09 Apr 12, 2024
fd747ac
Export middleware types
dac09 Apr 12, 2024
a308c12
Rename file for middleware
dac09 Apr 12, 2024
1226f55
Tweaks to get it further
dac09 Apr 12, 2024
f7ac767
Get it working for serve!
dac09 Apr 12, 2024
348ea7f
Get it to import component in dev too
dac09 Apr 12, 2024
8fe05b2
Only update inputs for ssrBuilds
dac09 Apr 12, 2024
3eff5fa
Update comments
dac09 Apr 15, 2024
0f5e872
Merge branch 'main' of github.com:redwoodjs/redwood into feat/dc-rc-o…
dac09 Apr 16, 2024
7d3adb8
set type=module and build for both esm and cjs
Tobbe Apr 16, 2024
3d95f45
Merge branch 'feat/dc-rc-og-gen-mw-p2' of github.com:redwoodjs/redwoo…
dac09 Apr 16, 2024
90d504d
Revert "set type=module and build for both esm and cjs"
dac09 Apr 16, 2024
4e466a0
Fix loading of CSS and Images in both prod and dev!
dac09 Apr 16, 2024
f2ee7c0
Update test
dac09 Apr 17, 2024
928e203
Use dist imports, leave moduleResolution as is
dac09 Apr 17, 2024
7a3e09c
Update ts templates and fixtures
dac09 Apr 17, 2024
d400fb4
Merge branch 'main' into feat/dc-rc-og-gen-mw-p2
dac09 Apr 17, 2024
871d04f
Merge branch 'main' into feat/dc-rc-og-gen-mw-p2
dac09 Apr 18, 2024
e79e6ac
Merge branch 'main' into feat/dc-rc-og-gen-mw-p2
dac09 Apr 18, 2024
99b6054
Initial tests for middleware
dac09 Apr 18, 2024
971607c
Add more tests for sub functions
dac09 Apr 18, 2024
e015b8a
Fix build and more tests around the middleware
dac09 Apr 18, 2024
ea17832
Merge branch 'main' into feat/dc-rc-og-gen-mw-p2
dac09 Apr 18, 2024
885134a
Merge branch 'main' of github.com:redwoodjs/redwood into feat/dc-rc-o…
dac09 Apr 19, 2024
0ed26f7
Update JS Template
dac09 Apr 19, 2024
9679058
That was hard!
dac09 Apr 19, 2024
95edfbd
LINT
dac09 Apr 19, 2024
e40e08b
Lint fixes
dac09 Apr 22, 2024
3bcb47b
Fix types
dac09 Apr 22, 2024
bcc7dae
Update dependency list
dac09 Apr 22, 2024
bae0489
Update scaffold generator to look for index.css instead of Routes
dac09 Apr 22, 2024
4cf78fb
Merge branch 'main' of github.com:redwoodjs/redwood into feat/dc-rc-o…
dac09 Apr 22, 2024
e03e399
Reorder index and scaffold css
dac09 Apr 22, 2024
e16eca4
Try posix paths
dac09 Apr 22, 2024
c7e707d
Add changesets
dac09 Apr 22, 2024
2e1d061
Ensure posix path again
dac09 Apr 22, 2024
f534c6a
Adds hooks test file
cannikin Apr 22, 2024
b857fe3
Merge branch 'main' of github.com:redwoodjs/redwood into feat/dc-rc-o…
dac09 Apr 23, 2024
fb4b091
Update webpack entry too
dac09 Apr 23, 2024
60a4fc3
Update changeset
dac09 Apr 23, 2024
beb4053
Add tests for screenshot size
dac09 Apr 23, 2024
b8625ab
Add test for default viewport size too
dac09 Apr 23, 2024
3c72c01
Update entry.server template for streaming ssr
dac09 Apr 23, 2024
78dd721
Update prerender too
dac09 Apr 23, 2024
496d90f
Always include pathname in hook output, fixed bad origin mock in tests
cannikin Apr 24, 2024
ba007f1
Merge branch 'main' into feat/dc-rc-og-gen-mw-p2
dac09 Apr 24, 2024
e05590d
Merge branch 'main' into feat/dc-rc-og-gen-mw-p2
dac09 Apr 25, 2024
8f2de47
Apply suggestions from code review
dac09 Apr 26, 2024
b9dd681
Merge branch 'main' of github.com:redwoodjs/redwood into feat/dc-rc-o…
dac09 Apr 26, 2024
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
45 changes: 45 additions & 0 deletions .changesets/10469.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
- feat(og-gen): Implement middleware and hooks (#10469) by @dac09

The OG Gen saga continues with @cannikin and @dac09 ⚔️

This PR:
- adds OgImageMiddleware and Hooks to `@redwoodjs/og-gen`, complete with tests

⚠️ Template changes:
- updates entry.client template to pass in Routes to App
- updates App to take children (i.e. Routes)

This is so that we can pass the OG component to be rendered _with_ your App's CSS setup.


**How to use this?**

1. **Registering the middleware:**
```ts
import OgImageMiddleware from '@redwoodjs/ogimage-gen/middleware'

export const registerMiddleware = () => {
const ogMw = new OgImageMiddleware({
App,
Document,
})

return [ogMw]
}
```

2. Configure your `vite.config.ts`
```ts
import vitePluginOgImageGen from '@redwoodjs/ogimage-gen/plugin'

const viteConfig: UserConfig = {
// 👇 so it builds your OG components
plugins: [redwood(), vitePluginOgImageGen()],
}

export default defineConfig(viteConfig)
```
3. Add your OG Image component next to the page it's for
e.g. web/src/pages/AboutPage/AboutPage.png.tsx

4. Use hooks on AboutPage to generate the ogURL
1 change: 1 addition & 0 deletions .vscode/settings.json
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@
"Flightcontrol",
"graphiql",
"memfs",
"OGIMAGE",
"opentelemetry",
"pino",
"Pistorius",
Expand Down
6 changes: 3 additions & 3 deletions __fixtures__/test-project/web/src/App.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,12 +4,12 @@ import { FatalErrorBoundary, RedwoodProvider } from '@redwoodjs/web'
import { RedwoodApolloProvider } from '@redwoodjs/web/apollo'

import FatalErrorPage from 'src/pages/FatalErrorPage'
import Routes from 'src/Routes'

import { AuthProvider, useAuth } from './auth'

import './scaffold.css'
import './index.css'
import './scaffold.css'

interface AppProps {
children?: ReactNode
}
Expand All @@ -19,7 +19,7 @@ const App = ({ children }: AppProps) => (
<RedwoodProvider titleTemplate="%PageTitle | %AppTitle">
<AuthProvider>
<RedwoodApolloProvider useAuth={useAuth}>
{children ? children : <Routes />}
{children}
</RedwoodApolloProvider>
</AuthProvider>
</RedwoodProvider>
Expand Down
15 changes: 13 additions & 2 deletions __fixtures__/test-project/web/src/entry.client.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
import { hydrateRoot, createRoot } from 'react-dom/client'

import App from './App'
import Routes from './Routes'

/**
* When `#redwood-app` isn't empty then it's very likely that you're using
* prerendering. So React attaches event listeners to the existing markup
Expand All @@ -16,8 +18,17 @@ if (!redwoodAppElement) {
}

if (redwoodAppElement.children?.length > 0) {
hydrateRoot(redwoodAppElement, <App />)
hydrateRoot(
redwoodAppElement,
<App>
<Routes />
</App>
)
} else {
const root = createRoot(redwoodAppElement)
root.render(<App />)
root.render(
<App>
<Routes />
</App>
)
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import { hydrateRoot, createRoot } from 'react-dom/client'

import App from './App'
import { Document } from './Document'
import Routes from './Routes'

/**
* When `#redwood-app` isn't empty then it's very likely that you're using
Expand All @@ -15,14 +16,18 @@ if (redwoodAppElement.children?.length > 0) {
hydrateRoot(
document,
<Document css={window.__assetMap?.()?.css}>
<App />
<App>
<Routes />
</App>
</Document>
)
} else {
const root = createRoot(document)
root.render(
<Document css={window.__assetMap?.()?.css}>
<App />
<App>
<Routes />
</App>
</Document>
)
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import type { TagDescriptor } from '@redwoodjs/web'

import App from './App'
import { Document } from './Document'
import Routes from './Routes'

interface Props {
css: string[]
Expand All @@ -11,7 +12,9 @@ interface Props {
export const ServerEntry: React.FC<Props> = ({ css, meta }) => {
return (
<Document css={css} meta={meta}>
<App />
<App>
<Routes />
</App>
</Document>
)
}
Original file line number Diff line number Diff line change
Expand Up @@ -70,12 +70,12 @@ describe('fragments graphQLClientConfig', () => {
import { RedwoodApolloProvider } from \"@redwoodjs/web/apollo\";

import FatalErrorPage from \"src/pages/FatalErrorPage\";
import Routes from \"src/Routes\";

import { AuthProvider, useAuth } from \"./auth\";

import \"./scaffold.css\";
import \"./index.css\";
import \"./scaffold.css\";

interface AppProps {
children?: ReactNode;
}
Expand All @@ -94,7 +94,7 @@ describe('fragments graphQLClientConfig', () => {
useAuth={useAuth}
graphQLClientConfig={graphQLClientConfig}
>
{children ? children : <Routes />}
{children}
</RedwoodApolloProvider>
</AuthProvider>
</RedwoodProvider>
Expand Down
4 changes: 2 additions & 2 deletions packages/cli/src/lib/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -441,8 +441,8 @@ export const addScaffoldImport = () => {
}

appJsContents = appJsContents.replace(
"import Routes from 'src/Routes'\n",
"import Routes from 'src/Routes'\n\nimport './scaffold.css'",
"import './index.css'",
"import './index.css'\nimport './scaffold.css'\n",
)
writeFile(appJsPath, appJsContents, { overwriteExisting: true })

Expand Down
1 change: 1 addition & 0 deletions packages/core/config/webpack.common.js
Original file line number Diff line number Diff line change
Expand Up @@ -240,6 +240,7 @@ module.exports = (webpackEnv) => {
'styled-components',
),
'~redwood-app-root': path.resolve(redwoodPaths.web.app),
'~redwood-app-routes': path.resolve(redwoodPaths.web.routes),
react: path.resolve(redwoodPaths.base, 'node_modules', 'react'),
'react-hook-form': path.resolve(
redwoodPaths.base,
Expand Down
5 changes: 1 addition & 4 deletions packages/create-redwood-app/templates/js/web/src/App.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,16 +2,13 @@ import { FatalErrorBoundary, RedwoodProvider } from '@redwoodjs/web'
import { RedwoodApolloProvider } from '@redwoodjs/web/apollo'

import FatalErrorPage from 'src/pages/FatalErrorPage'
import Routes from 'src/Routes'

import './index.css'

const App = ({ children }) => (
<FatalErrorBoundary page={FatalErrorPage}>
<RedwoodProvider titleTemplate="%PageTitle | %AppTitle">
<RedwoodApolloProvider>
{children ? children : <Routes />}
</RedwoodApolloProvider>
<RedwoodApolloProvider>{children}</RedwoodApolloProvider>
</RedwoodProvider>
</FatalErrorBoundary>
)
Expand Down
15 changes: 13 additions & 2 deletions packages/create-redwood-app/templates/js/web/src/entry.client.jsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
import { hydrateRoot, createRoot } from 'react-dom/client'

import App from './App'
import Routes from './Routes'

/**
* When `#redwood-app` isn't empty then it's very likely that you're using
* prerendering. So React attaches event listeners to the existing markup
Expand All @@ -16,8 +18,17 @@ if (!redwoodAppElement) {
}

if (redwoodAppElement.children?.length > 0) {
hydrateRoot(redwoodAppElement, <App />)
hydrateRoot(
redwoodAppElement,
<App>
<Routes />
</App>
)
} else {
const root = createRoot(redwoodAppElement)
root.render(<App />)
root.render(
<App>
<Routes />
</App>
)
}
5 changes: 1 addition & 4 deletions packages/create-redwood-app/templates/ts/web/src/App.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@ import { FatalErrorBoundary, RedwoodProvider } from '@redwoodjs/web'
import { RedwoodApolloProvider } from '@redwoodjs/web/apollo'

import FatalErrorPage from 'src/pages/FatalErrorPage'
import Routes from 'src/Routes'

import './index.css'
interface AppProps {
Expand All @@ -14,9 +13,7 @@ interface AppProps {
const App = ({ children }: AppProps) => (
<FatalErrorBoundary page={FatalErrorPage}>
<RedwoodProvider titleTemplate="%PageTitle | %AppTitle">
<RedwoodApolloProvider>
{children ? children : <Routes />}
</RedwoodApolloProvider>
<RedwoodApolloProvider>{children}</RedwoodApolloProvider>
</RedwoodProvider>
</FatalErrorBoundary>
)
Expand Down
15 changes: 13 additions & 2 deletions packages/create-redwood-app/templates/ts/web/src/entry.client.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
import { hydrateRoot, createRoot } from 'react-dom/client'

import App from './App'
import Routes from './Routes'

/**
* When `#redwood-app` isn't empty then it's very likely that you're using
* prerendering. So React attaches event listeners to the existing markup
Expand All @@ -16,8 +18,17 @@ if (!redwoodAppElement) {
}

if (redwoodAppElement.children?.length > 0) {
hydrateRoot(redwoodAppElement, <App />)
hydrateRoot(
redwoodAppElement,
<App>
<Routes />
</App>
)
} else {
const root = createRoot(redwoodAppElement)
root.render(<App />)
root.render(
<App>
<Routes />
</App>
)
}
4 changes: 2 additions & 2 deletions packages/internal/src/routes.ts
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,7 @@ export interface RWRouteManifestItem {
routeHooks: string | null
bundle: string | null
hasParams: boolean
relativeFilePath: string | undefined
relativeFilePath: string
redirect: { to: string; permanent: boolean } | null
// Probably want isNotFound here, so we can attach a separate 404 handler
}
Expand All @@ -80,7 +80,7 @@ export interface RouteSpec extends RWRouteManifestItem {
id: string
isNotFound: boolean
filePath: string | undefined
relativeFilePath: string | undefined
relativeFilePath: string
}

export const getProjectRoutes = (): RouteSpec[] => {
Expand Down
3 changes: 3 additions & 0 deletions packages/ogimage-gen/cjsWrappers/hooks.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
/* eslint-env node */

module.exports = require('../dist/hooks.js').default
3 changes: 3 additions & 0 deletions packages/ogimage-gen/cjsWrappers/middleware.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
/* eslint-env node */

module.exports = require('../dist/OgImageMiddleware.js').default
18 changes: 14 additions & 4 deletions packages/ogimage-gen/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -8,12 +8,20 @@
},
"license": "MIT",
"exports": {
".": {
"default": "./dist/index.js"
},
"./plugin": {
"import": "./dist/vite-plugin-ogimage-gen.js",
"default": "./cjsWrappers/plugin.js"
"default": "./cjsWrappers/plugin.js",
"types": "./dist/vite-plugin-ogimage-gen.d.ts"
},
"./middleware": {
"import": "./dist/OgImageMiddleware.js",
"default": "./cjsWrappers/middleware.js",
"types": "./dist/OgImageMiddleware.d.ts"
},
"./hooks": {
"import": "./dist/hooks.js",
"default": "./cjsWrappers/hooks.js",
"types": "./dist/hooks.d.ts"
}
},
"files": [
Expand All @@ -34,10 +42,12 @@
"@redwoodjs/router": "workspace:*",
"@redwoodjs/vite": "workspace:*",
"fast-glob": "3.3.2",
"lodash": "4.17.21",
"react": "19.0.0-canary-cb151849e1-20240424",
"react-dom": "19.0.0-canary-cb151849e1-20240424"
},
"devDependencies": {
"@playwright/test": "1.42.1",
"@redwoodjs/framework-tools": "workspace:*",
"ts-toolbelt": "9.6.0",
"tsx": "4.7.1",
Expand Down
Loading
Loading